From 7a7a2df434cec5614271666b84b2ea1f41048e91 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 21 Nov 2015 12:01:22 +0100 Subject: ALSA: azt3328: Remove unnecessary synchronize_irq() before free_irq() Calling synchronize_irq() right before free_irq() is quite useless. On one hand the IRQ can easily fire again before free_irq() is entered, on the other hand free_irq() itself calls synchronize_irq() internally (in a race condition free way) before any state associated with the IRQ is freed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Takashi Iwai --- sound/pci/azt3328.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 07a4acc99541..5e2ef0bb7057 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -2294,8 +2294,6 @@ snd_azf3328_free(struct snd_azf3328 *chip) snd_azf3328_timer_stop(chip->timer); snd_azf3328_gameport_free(chip); - if (chip->irq >= 0) - synchronize_irq(chip->irq); __end_hw: if (chip->irq >= 0) free_irq(chip->irq, chip); -- cgit 1.4.1 From 5df29bca125277eec68fc31c0c0ba41b9a3cb78b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 29 Nov 2015 18:25:24 +0100 Subject: ALSA: i2c: constify snd_i2c_ops structures The snd_i2c_ops structures are never modified, so declare them as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Takashi Iwai --- include/sound/i2c.h | 2 +- sound/i2c/i2c.c | 2 +- sound/pci/ice1712/delta.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/include/sound/i2c.h b/include/sound/i2c.h index d125ff8c85e8..835254de2039 100644 --- a/include/sound/i2c.h +++ b/include/sound/i2c.h @@ -66,7 +66,7 @@ struct snd_i2c_bus { struct snd_i2c_bit_ops *bit; void *ops; } hw_ops; /* lowlevel operations */ - struct snd_i2c_ops *ops; /* midlevel operations */ + const struct snd_i2c_ops *ops; /* midlevel operations */ unsigned long private_value; void *private_data; diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c index 4677037f0c8e..ef2a9afe9e19 100644 --- a/sound/i2c/i2c.c +++ b/sound/i2c/i2c.c @@ -39,7 +39,7 @@ static int snd_i2c_bit_readbytes(struct snd_i2c_device *device, static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus, unsigned short addr); -static struct snd_i2c_ops snd_i2c_bit_ops = { +static const struct snd_i2c_ops snd_i2c_bit_ops = { .sendbytes = snd_i2c_bit_sendbytes, .readbytes = snd_i2c_bit_readbytes, .probeaddr = snd_i2c_bit_probeaddr, diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 496dbd0ad5db..3bfdc78cbc5f 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -174,7 +174,7 @@ static int ap_cs8427_probeaddr(struct snd_i2c_bus *bus, unsigned short addr) return -ENOENT; } -static struct snd_i2c_ops ap_cs8427_i2c_ops = { +static const struct snd_i2c_ops ap_cs8427_i2c_ops = { .sendbytes = ap_cs8427_sendbytes, .readbytes = ap_cs8427_readbytes, .probeaddr = ap_cs8427_probeaddr, -- cgit 1.4.1 From b03d61d646c596efd02db64df43d287ea596b663 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Thu, 3 Dec 2015 15:46:57 +0100 Subject: ALSA: hda - Enable power_save_node for CX20722 I've tested it on one device and it works fine, no clicks. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index c8b8ef5246a6..19b3deba23e4 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -901,6 +901,9 @@ static int patch_conexant_auto(struct hda_codec *codec) snd_hda_pick_fixup(codec, cxt5051_fixup_models, cxt5051_fixups, cxt_fixups); break; + case 0x14f150f2: + codec->power_save_node = 1; + /* Fall through */ default: codec->pin_amp_workaround = 1; snd_hda_pick_fixup(codec, cxt5066_fixup_models, -- cgit 1.4.1 From eb399d3c99d8b411bfc46e67ea329ddc1ca64e87 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Nov 2015 14:53:35 +0100 Subject: ALSA: hda - Skip ELD notification during PM process The ELD notification can be received asynchronously from the graphics side, and this may happen just at the moment the sound driver is processing the suspend or the resume, and it would confuse the whole procedure. Since the ELD and connection states are updated in anyway at the end of the resume, we can skip it when received during PM process. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 4b6fb668c91c..da264e8acce2 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -2357,6 +2357,9 @@ static void intel_pin_eld_notify(void *audio_ptr, int port) */ if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0) return; + /* ditto during suspend/resume process itself */ + if (atomic_read(&(codec)->core.in_pm)) + return; check_presence_and_report(codec, pin_nid); } -- cgit 1.4.1 From 18014fd793d5e73eec5f2c22eaa37a32b44748eb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 13 Nov 2015 12:51:49 +0100 Subject: ALSA: hda - Do zero-clear in snd_hdmi_parse_eld() itself Instead of doing in each caller side, snd_hdmi_parse_eld() does zero-clear of the parsed data by itself. This is safer and simplifies the upcoming code changes. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_eld.c | 1 + sound/pci/hda/patch_hdmi.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 563984dd2562..bc2e08257c2e 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -253,6 +253,7 @@ int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e, int mnl; int i; + memset(e, 0, sizeof(*e)); e->eld_ver = GRAB_BITS(buf, 0, 3, 5); if (e->eld_ver != ELD_VER_CEA_861D && e->eld_ver != ELD_VER_PARTIAL) { diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index da264e8acce2..901a3a7248ed 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1570,7 +1570,6 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) &eld->eld_size) < 0) eld->eld_valid = false; else { - memset(&eld->info, 0, sizeof(struct parsed_hdmi_eld)); if (snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer, eld->eld_size) < 0) eld->eld_valid = false; -- cgit 1.4.1 From e90247f9fceeebe5bdaac2d87e301e73bae9bc1f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 13 Nov 2015 09:12:12 +0100 Subject: ALSA: hda - Split ELD update code from hdmi_present_sense() This is a preliminary patch for the later change to support ELD/jack handling with i915 audio component. This splits the ELD update code from hdmi_present_sense() so that it can be called from other places. Just a code refactoring, no functional change. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 108 ++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 54 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 901a3a7248ed..a918377d3e9b 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1530,6 +1530,56 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) return 0; } +/* update per_pin ELD from the given new ELD; + * setup info frame and notification accordingly + */ +static void update_eld(struct hda_codec *codec, + struct hdmi_spec_per_pin *per_pin, + struct hdmi_eld *eld) +{ + struct hdmi_eld *pin_eld = &per_pin->sink_eld; + bool old_eld_valid = pin_eld->eld_valid; + bool eld_changed; + + if (eld->eld_valid) + snd_hdmi_show_eld(codec, &eld->info); + + eld_changed = (pin_eld->eld_valid != eld->eld_valid); + if (eld->eld_valid && pin_eld->eld_valid) + if (pin_eld->eld_size != eld->eld_size || + memcmp(pin_eld->eld_buffer, eld->eld_buffer, + eld->eld_size) != 0) + eld_changed = true; + + pin_eld->eld_valid = eld->eld_valid; + pin_eld->eld_size = eld->eld_size; + if (eld->eld_valid) + memcpy(pin_eld->eld_buffer, eld->eld_buffer, eld->eld_size); + pin_eld->info = eld->info; + + /* + * Re-setup pin and infoframe. This is needed e.g. when + * - sink is first plugged-in + * - transcoder can change during stream playback on Haswell + * and this can make HW reset converter selection on a pin. + */ + if (eld->eld_valid && !old_eld_valid && per_pin->setup) { + if (is_haswell_plus(codec) || is_valleyview_plus(codec)) { + intel_verify_pin_cvt_connect(codec, per_pin); + intel_not_share_assigned_cvt(codec, per_pin->pin_nid, + per_pin->mux_idx); + } + + hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm); + } + + if (eld_changed) + snd_ctl_notify(codec->card, + SNDRV_CTL_EVENT_MASK_VALUE | + SNDRV_CTL_EVENT_MASK_INFO, + &per_pin->eld_ctl->id); +} + static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) { struct hda_jack_tbl *jack; @@ -1547,8 +1597,6 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) * the unsolicited response to avoid custom WARs. */ int present; - bool update_eld = false; - bool eld_changed = false; bool ret; snd_hda_power_up_pm(codec); @@ -1574,61 +1622,13 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) eld->eld_size) < 0) eld->eld_valid = false; } - - if (eld->eld_valid) { - snd_hdmi_show_eld(codec, &eld->info); - update_eld = true; - } - else if (repoll) { - schedule_delayed_work(&per_pin->work, - msecs_to_jiffies(300)); - goto unlock; - } } - if (pin_eld->eld_valid != eld->eld_valid) - eld_changed = true; - - if (pin_eld->eld_valid && !eld->eld_valid) - update_eld = true; - - if (update_eld) { - bool old_eld_valid = pin_eld->eld_valid; - pin_eld->eld_valid = eld->eld_valid; - if (pin_eld->eld_size != eld->eld_size || - memcmp(pin_eld->eld_buffer, eld->eld_buffer, - eld->eld_size) != 0) { - memcpy(pin_eld->eld_buffer, eld->eld_buffer, - eld->eld_size); - eld_changed = true; - } - pin_eld->eld_size = eld->eld_size; - pin_eld->info = eld->info; - - /* - * Re-setup pin and infoframe. This is needed e.g. when - * - sink is first plugged-in (infoframe is not set up if !monitor_present) - * - transcoder can change during stream playback on Haswell - * and this can make HW reset converter selection on a pin. - */ - if (eld->eld_valid && !old_eld_valid && per_pin->setup) { - if (is_haswell_plus(codec) || - is_valleyview_plus(codec)) { - intel_verify_pin_cvt_connect(codec, per_pin); - intel_not_share_assigned_cvt(codec, pin_nid, - per_pin->mux_idx); - } - - hdmi_setup_audio_infoframe(codec, per_pin, - per_pin->non_pcm); - } - } + if (!eld->eld_valid && repoll) + schedule_delayed_work(&per_pin->work, msecs_to_jiffies(300)); + else + update_eld(codec, per_pin, eld); - if (eld_changed) - snd_ctl_notify(codec->card, - SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, - &per_pin->eld_ctl->id); - unlock: ret = !repoll || !pin_eld->monitor_present || pin_eld->eld_valid; jack = snd_hda_jack_tbl_get(codec, pin_nid); -- cgit 1.4.1 From 6603249dcdbb6aab0b726bdf372d6f20c0d2d611 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 1 Dec 2015 16:49:35 +0100 Subject: ALSA: hda - Enable audio component for old Intel PCH devices As i915 graphics driver provides the notification via audio component, not only the currently implemented HSW+ and VLV+ platforms but also all other PCH-based platforms (e.g. Cougar Point, Panther Point, etc) can use this infrastructure. It'll improve the reliability and the power consumption significantly, especially once when we implement the ELD notification via component. As a preliminary, this patch enables the usage of audio component for all PCH platforms. The HDA controller just needs to set AZX_DCAPS_I915_POWERWELL flag appropriately. The name of the flag is a bit confusing, but this actually works even on the chips without the powerwell but accesses only the other component ops. In the HDMI/DP codec driver side, we just need to register/unregister the notifier for such chips. This can be identified by checking the audio_component field in the assigned hdac_bus. One caveat is that PCH for Haswell and Broadwell must not be bound with i915 audio component, as there are dedicated HD-audio HDMI controllers on these platforms. Ditto for Poulsbo and Oaktrail as they use gma500 graphics, not i915. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 14 ++++++++++---- sound/pci/hda/patch_hdmi.c | 6 ++++-- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 963f82430938..ee0e316401f9 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -284,13 +284,19 @@ enum { (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE) /* quirks for Intel PCH */ -#define AZX_DCAPS_INTEL_PCH_NOPM \ +#define AZX_DCAPS_INTEL_PCH_BASE \ (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\ AZX_DCAPS_REVERSE_ASSIGN | AZX_DCAPS_SNOOP_TYPE(SCH)) +/* PCH up to IVB; bound with i915 audio component for HDMI, no runtime PM */ +#define AZX_DCAPS_INTEL_PCH_NOPM \ + (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_POWERWELL) + +/* PCH for HSW/BDW; with runtime PM, but no i915 binding */ #define AZX_DCAPS_INTEL_PCH \ - (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME) + (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME) +/* HSW HDMI */ #define AZX_DCAPS_INTEL_HASWELL \ (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\ AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\ @@ -2146,10 +2152,10 @@ static const struct pci_device_id azx_ids[] = { .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, /* Poulsbo */ { PCI_DEVICE(0x8086, 0x811b), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE }, /* Oaktrail */ { PCI_DEVICE(0x8086, 0x080a), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE }, /* BayTrail */ { PCI_DEVICE(0x8086, 0x0f04), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL }, diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index a918377d3e9b..85342d261043 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -152,6 +152,8 @@ struct hdmi_spec { struct i915_audio_component_audio_ops i915_audio_ops; }; +#define codec_has_acomp(codec) \ + ((codec)->bus->core.audio_component != NULL) struct hdmi_audio_infoframe { u8 type; /* 0x84 */ @@ -2218,7 +2220,7 @@ static void generic_hdmi_free(struct hda_codec *codec) struct hdmi_spec *spec = codec->spec; int pin_idx; - if (is_haswell_plus(codec) || is_valleyview_plus(codec)) + if (codec_has_acomp(codec)) snd_hdac_i915_register_notifier(NULL); for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { @@ -2390,7 +2392,7 @@ static int patch_generic_hdmi(struct hda_codec *codec) is_broxton(codec)) codec->core.link_power_control = 1; - if (is_haswell_plus(codec) || is_valleyview_plus(codec)) { + if (codec_has_acomp(codec)) { codec->depop_delay = 0; spec->i915_audio_ops.audio_ptr = codec; spec->i915_audio_ops.pin_eld_notify = intel_pin_eld_notify; -- cgit 1.4.1 From 1e73bf781546f3969039fe60bff1eca44c87c241 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 8 Dec 2015 11:47:31 +0100 Subject: ALSA: hda - Remove unused snd_hda_get_nid_path() An exported helper function snd_hda_get_nid_path() is nowhere used. Let's remove it. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 16 ---------------- sound/pci/hda/hda_generic.h | 2 -- 2 files changed, 18 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index c6e8a651cea1..a644fc3302f0 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -278,22 +278,6 @@ static struct nid_path *get_nid_path(struct hda_codec *codec, return NULL; } -/** - * snd_hda_get_nid_path - get the path between the given NIDs - * @codec: the HDA codec - * @from_nid: the NID where the path start from - * @to_nid: the NID where the path ends at - * - * Return the found nid_path object or NULL for error. - * Passing 0 to either @from_nid or @to_nid behaves as a wildcard. - */ -struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, - hda_nid_t from_nid, hda_nid_t to_nid) -{ - return get_nid_path(codec, from_nid, to_nid, 0); -} -EXPORT_SYMBOL_GPL(snd_hda_get_nid_path); - /** * snd_hda_get_path_idx - get the index number corresponding to the path * instance diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 56e4139b9032..692510e59365 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -306,8 +306,6 @@ int snd_hda_gen_spec_init(struct hda_gen_spec *spec); int snd_hda_gen_init(struct hda_codec *codec); void snd_hda_gen_free(struct hda_codec *codec); -struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, - hda_nid_t from_nid, hda_nid_t to_nid); int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path); struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx); bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, -- cgit 1.4.1 From c4a58c308a459901827ac941d40d5db047a1cb71 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 8 Dec 2015 11:48:39 +0100 Subject: ALSA: hda - Make snd_hda_parse_nid_path() local An exported function snd_hda_parse_nid_path() is used only inside hda_generic.c. Let's make it a static local function for a better code optimization. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 5 ++--- sound/pci/hda/hda_generic.h | 3 --- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index a644fc3302f0..f3c058f6c831 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -435,7 +435,7 @@ static bool __parse_nid_path(struct hda_codec *codec, return true; } -/** +/* * snd_hda_parse_nid_path - parse the widget path from the given nid to * the target nid * @codec: the HDA codec @@ -454,7 +454,7 @@ static bool __parse_nid_path(struct hda_codec *codec, * with the negative of given value are excluded, only other paths are chosen. * when @anchor_nid is zero, no special handling about path selection. */ -bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, +static bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, hda_nid_t to_nid, int anchor_nid, struct nid_path *path) { @@ -465,7 +465,6 @@ bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, } return false; } -EXPORT_SYMBOL_GPL(snd_hda_parse_nid_path); /** * snd_hda_add_new_path - parse the path between the given NIDs and diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 692510e59365..f66fc7e25e07 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -308,9 +308,6 @@ void snd_hda_gen_free(struct hda_codec *codec); int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path); struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx); -bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, - hda_nid_t to_nid, int anchor_nid, - struct nid_path *path); struct nid_path * snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, hda_nid_t to_nid, int anchor_nid); -- cgit 1.4.1 From e7fdd52779a6c2b49d457f452296a77c8cffef6a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 8 Dec 2015 17:00:42 +0100 Subject: ALSA: hda - Implement loopback control switch for Realtek and other codecs Many codecs, typically found on Realtek codecs, have the analog loopback path merged to the secondary input of the middle of the output paths. Currently, we don't offer the dynamic switching in such configuration but let each loopback path mute by itself. This should work well in theory, but in reality, we often see that such a dead loopback path causes some background noises even if all the elements get muted. Such a problem has been fixed by adding the quirk accordingly to disable aamix, and it's the right fix, per se. The only problem is that it's not so trivial to achieve it; user needs to pass a hint string via patch module option or sysfs. This patch gives a bit improvement on the situation: it adds "Loopback Mixing" control element for such codecs like other codecs (e.g. IDT or VIA codecs) with the individual loopback paths. User can turn on/off the loopback path simply via a mixer app. For keeping the compatibility, the loopback is still enabled on these codecs. But user can try to turn it off if experiencing a suspicious background or click noise on the fly, then build a static fixup later once after the problem is addressed. Other than the addition of the loopback enable/disablement control, there should be no changes. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 87 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 19 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index f3c058f6c831..30c8efe0f80a 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -754,9 +754,6 @@ static void activate_amp(struct hda_codec *codec, hda_nid_t nid, int dir, unsigned int caps; unsigned int mask, val; - if (!enable && is_active_nid(codec, nid, dir, idx_to_check)) - return; - caps = query_amp_caps(codec, nid, dir); val = get_amp_val_to_activate(codec, nid, dir, caps, enable); mask = get_amp_mask_to_modify(codec, nid, dir, idx_to_check, caps); @@ -767,12 +764,22 @@ static void activate_amp(struct hda_codec *codec, hda_nid_t nid, int dir, update_amp(codec, nid, dir, idx, mask, val); } +static void check_and_activate_amp(struct hda_codec *codec, hda_nid_t nid, + int dir, int idx, int idx_to_check, + bool enable) +{ + /* check whether the given amp is still used by others */ + if (!enable && is_active_nid(codec, nid, dir, idx_to_check)) + return; + activate_amp(codec, nid, dir, idx, idx_to_check, enable); +} + static void activate_amp_out(struct hda_codec *codec, struct nid_path *path, int i, bool enable) { hda_nid_t nid = path->path[i]; init_amp(codec, nid, HDA_OUTPUT, 0); - activate_amp(codec, nid, HDA_OUTPUT, 0, 0, enable); + check_and_activate_amp(codec, nid, HDA_OUTPUT, 0, 0, enable); } static void activate_amp_in(struct hda_codec *codec, struct nid_path *path, @@ -800,9 +807,16 @@ static void activate_amp_in(struct hda_codec *codec, struct nid_path *path, * when aa-mixer is available, we need to enable the path as well */ for (n = 0; n < nums; n++) { - if (n != idx && (!add_aamix || conn[n] != spec->mixer_merge_nid)) - continue; - activate_amp(codec, nid, HDA_INPUT, n, idx, enable); + if (n != idx) { + if (conn[n] != spec->mixer_merge_nid) + continue; + /* when aamix is disabled, force to off */ + if (!add_aamix) { + activate_amp(codec, nid, HDA_INPUT, n, n, false); + continue; + } + } + check_and_activate_amp(codec, nid, HDA_INPUT, n, idx, enable); } } @@ -1563,6 +1577,12 @@ static bool map_singles(struct hda_codec *codec, int outs, return found; } +static inline bool has_aamix_out_paths(struct hda_gen_spec *spec) +{ + return spec->aamix_out_paths[0] || spec->aamix_out_paths[1] || + spec->aamix_out_paths[2]; +} + /* create a new path including aamix if available, and return its index */ static int check_aamix_out_path(struct hda_codec *codec, int path_idx) { @@ -2405,25 +2425,51 @@ static void update_aamix_paths(struct hda_codec *codec, bool do_mix, } } +/* re-initialize the output paths; only called from loopback_mixing_put() */ +static void update_output_paths(struct hda_codec *codec, int num_outs, + const int *paths) +{ + struct hda_gen_spec *spec = codec->spec; + struct nid_path *path; + int i; + + for (i = 0; i < num_outs; i++) { + path = snd_hda_get_path_from_idx(codec, paths[i]); + if (path) + snd_hda_activate_path(codec, path, path->active, + spec->aamix_mode); + } +} + static int loopback_mixing_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct hda_gen_spec *spec = codec->spec; + const struct auto_pin_cfg *cfg = &spec->autocfg; unsigned int val = ucontrol->value.enumerated.item[0]; if (val == spec->aamix_mode) return 0; spec->aamix_mode = val; - update_aamix_paths(codec, val, spec->out_paths[0], - spec->aamix_out_paths[0], - spec->autocfg.line_out_type); - update_aamix_paths(codec, val, spec->hp_paths[0], - spec->aamix_out_paths[1], - AUTO_PIN_HP_OUT); - update_aamix_paths(codec, val, spec->speaker_paths[0], - spec->aamix_out_paths[2], - AUTO_PIN_SPEAKER_OUT); + if (has_aamix_out_paths(spec)) { + update_aamix_paths(codec, val, spec->out_paths[0], + spec->aamix_out_paths[0], + cfg->line_out_type); + update_aamix_paths(codec, val, spec->hp_paths[0], + spec->aamix_out_paths[1], + AUTO_PIN_HP_OUT); + update_aamix_paths(codec, val, spec->speaker_paths[0], + spec->aamix_out_paths[2], + AUTO_PIN_SPEAKER_OUT); + } else { + update_output_paths(codec, cfg->line_outs, spec->out_paths); + if (cfg->line_out_type != AUTO_PIN_HP_OUT) + update_output_paths(codec, cfg->hp_outs, spec->hp_paths); + if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) + update_output_paths(codec, cfg->speaker_outs, + spec->speaker_paths); + } return 1; } @@ -2441,12 +2487,13 @@ static int create_loopback_mixing_ctl(struct hda_codec *codec) if (!spec->mixer_nid) return 0; - if (!(spec->aamix_out_paths[0] || spec->aamix_out_paths[1] || - spec->aamix_out_paths[2])) - return 0; if (!snd_hda_gen_add_kctl(spec, NULL, &loopback_mixing_enum)) return -ENOMEM; spec->have_aamix_ctl = 1; + /* if no explicit aamix path is present (e.g. for Realtek codecs), + * enable aamix as default -- just for compatibility + */ + spec->aamix_mode = !has_aamix_out_paths(spec); return 0; } @@ -5647,6 +5694,8 @@ static void init_aamix_paths(struct hda_codec *codec) if (!spec->have_aamix_ctl) return; + if (!has_aamix_out_paths(spec)) + return; update_aamix_paths(codec, spec->aamix_mode, spec->out_paths[0], spec->aamix_out_paths[0], spec->autocfg.line_out_type); -- cgit 1.4.1 From 6ee8eeb4af0e91975a7cd4795925e499cc79503c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 9 Dec 2015 07:13:48 +0100 Subject: ALSA: hda - Less grumbling about lack of i915 binding The recent commit [6603249dcdbb: ALSA: hda - Enable audio component for old Intel PCH devices] enabled the i915 binding for HDMI/DP on old Intel PCHs. But many boards are without HDMI/DP, and they actually don't need i915 binding, and yet the driver has a check of i915 binding and complains like Haswell must be built with CONFIG_SND_HDA_I915 This error is false-positive, and it should be put only for HSW/BDW, instead of all devices that may be bound with i915. This patch fixes the condition to check, as well as rephrasing the message specific to HSW/BDW HDMI/DP. Fixes: 6603249dcdbb ('ALSA: hda - Enable audio component for old Intel PCH devices') Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ee0e316401f9..b49547f3c2e9 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1954,8 +1954,8 @@ static int azx_probe(struct pci_dev *pci, #endif /* CONFIG_SND_HDA_PATCH_LOADER */ #ifndef CONFIG_SND_HDA_I915 - if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) - dev_err(card->dev, "Haswell must build in CONFIG_SND_HDA_I915\n"); + if (CONTROLLER_IN_GPU(pci)) + dev_err(card->dev, "Haswell/Broadwell HDMI/DP must build in CONFIG_SND_HDA_I915\n"); #endif if (schedule_probe) -- cgit 1.4.1 From fbaf9f9f6158a9c07652df88dd0bd68132b93292 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 9 Dec 2015 07:21:49 +0100 Subject: ALSA: hda - Don't try to bind i915 unless CONFIG_SND_HDA_I915 is set snd-hda-intel driver tries to bind with i915 audio component always when AZX_DCAPS_I915_POWERWELL is set in the driver caps. This was mostly OK in the past, as the flag was applied only to a limited set of devices, namely, Haswell and Broadwell. On these machines, i915 graphics is almost mandatory as long as HDMI/DP is concerned. Recently the application of i915 binding was widened to more Intel chips. On these chips, the chance of a kernel without i915 graphics is much higher, and such user would hit an error like: snd_hda_intel 0000:00:1b.0: failed to add i915 component master (-19) Although the error itself is harmless, it's certainly superfluous even to try binding with i915, if we already know that there isn't any. This patch fixes it by simply defining AZX_DCAPS_I915_POWERWELL as 0 in the case without i915. Then all codes referring to this flag will be optimized out by the compiler. Fixes: 6603249dcdbb ('ALSA: hda - Enable audio component for old Intel PCH devices') Reported-by: kernel test robot Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_controller.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index 7b635d68cfe1..c1d28a657f19 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -46,7 +46,11 @@ #define AZX_DCAPS_REVERSE_ASSIGN (1 << 24) /* Assign devices in reverse order */ #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 #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 */ -- cgit 1.4.1 From f4e3040bf0e94ff86ba2c970a4d7691100dc69d5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 10 Dec 2015 13:01:28 +0100 Subject: ALSA: hda - Optimize audio component check in patch_hdmi.c The audio component is enabled only when CONFIG_SND_HDA_I915 is set. Give a dummy macro for allowing the compiler optimize out the relevant codes when this Kconfig isn't set. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 85342d261043..44d0d2374bb6 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -152,8 +152,12 @@ struct hdmi_spec { struct i915_audio_component_audio_ops i915_audio_ops; }; +#ifdef CONFIG_SND_HDA_I915 #define codec_has_acomp(codec) \ ((codec)->bus->core.audio_component != NULL) +#else +#define codec_has_acomp(codec) false +#endif struct hdmi_audio_infoframe { u8 type; /* 0x84 */ -- cgit 1.4.1 From 55913110dde2d9c1cf751481525848644f9041da Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 10 Dec 2015 13:03:29 +0100 Subject: ALSA: hda - Allow i915 binding later in codec driver Due to the recent change, HDA controller driver for Intel PCH tries to bind i915 audio component always at the probe time no matter whether HDMI/DP codec is found. This is, however, superflulous for old chipsets (e.g. on IVB) where they don't have always the HDMI/DP codecs but often have only a discrete GPU instead. For the newer chipsets, we need already the i915 binding from the beginning due to power well control. Meanwhile, for older chipsets where we don't need power well, we don't need the i915 binding at the controller level. This patch removes again the i915 binding in the HDA controller driver for old Intel PCHs, but adds the binding in HDMI/DP codec driver instead. This allows still the use of the direct notification from the graphics driver while we can avoid the unnecessary load of i915 driver for machines only with another GPU. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 6 +++--- sound/pci/hda/patch_hdmi.c | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b49547f3c2e9..fe9bef339cea 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -288,11 +288,11 @@ enum { (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\ AZX_DCAPS_REVERSE_ASSIGN | AZX_DCAPS_SNOOP_TYPE(SCH)) -/* PCH up to IVB; bound with i915 audio component for HDMI, no runtime PM */ +/* PCH up to IVB; no runtime PM */ #define AZX_DCAPS_INTEL_PCH_NOPM \ - (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_POWERWELL) + (AZX_DCAPS_INTEL_PCH_BASE) -/* PCH for HSW/BDW; with runtime PM, but no i915 binding */ +/* PCH for HSW/BDW; with runtime PM */ #define AZX_DCAPS_INTEL_PCH \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 44d0d2374bb6..35a78a6f87a6 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -150,6 +150,7 @@ struct hdmi_spec { /* i915/powerwell (Haswell+/Valleyview+) specific */ struct i915_audio_component_audio_ops i915_audio_ops; + bool i915_bound; /* was i915 bound in this driver? */ }; #ifdef CONFIG_SND_HDA_I915 @@ -2234,6 +2235,8 @@ static void generic_hdmi_free(struct hda_codec *codec) eld_proc_free(per_pin); } + if (spec->i915_bound) + snd_hdac_i915_exit(&codec->bus->core); hdmi_array_free(spec); kfree(spec); } @@ -2381,6 +2384,12 @@ static int patch_generic_hdmi(struct hda_codec *codec) codec->spec = spec; hdmi_array_init(spec, 4); + /* Try to bind with i915 for any Intel codecs (if not done yet) */ + if (!codec_has_acomp(codec) && + (codec->core.vendor_id >> 16) == 0x8086) + if (!snd_hdac_i915_init(&codec->bus->core)) + spec->i915_bound = true; + if (is_haswell_plus(codec)) { intel_haswell_enable_all_pins(codec, true); intel_haswell_fixup_enable_dp12(codec); @@ -2404,6 +2413,8 @@ static int patch_generic_hdmi(struct hda_codec *codec) } if (hdmi_parse_codec(codec) < 0) { + if (spec->i915_bound) + snd_hdac_i915_exit(&codec->bus->core); codec->spec = NULL; kfree(spec); return -EINVAL; -- cgit 1.4.1 From 9a5e5234bafeaa2e9d15881d443c38d3d82d0b38 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 10 Dec 2015 14:35:09 +0100 Subject: ALSA: hda - Fix superfluous HDMI jack repoll The recent commit [e90247f9fcee: ALSA: hda - Split ELD update code from hdmi_present_sense()] rewrote the HDMI jack handling code, but a slight behavior change sneaked in unexpectedly. When the jack isn't connected, it tries repoll unnecessarily. This patch addresses the flaw, to the right behavior as before. Fixes: e90247f9fcee ('ALSA: hda - Split ELD update code from hdmi_present_sense()') Reported-and-tested-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 35a78a6f87a6..2a7d29a07f31 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1605,6 +1605,7 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) */ int present; bool ret; + bool do_repoll = false; snd_hda_power_up_pm(codec); present = snd_hda_pin_sense(codec, pin_nid); @@ -1629,9 +1630,11 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) eld->eld_size) < 0) eld->eld_valid = false; } + if (!eld->eld_valid && repoll) + do_repoll = true; } - if (!eld->eld_valid && repoll) + if (do_repoll) schedule_delayed_work(&per_pin->work, msecs_to_jiffies(300)); else update_eld(codec, per_pin, eld); -- cgit 1.4.1 From 788d441a164caea0a5d82e1d5bcd161820bfe62a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Nov 2015 15:36:13 +0100 Subject: ALSA: hda - Use component ops for i915 HDMI/DP audio jack handling Since we have a new audio component ops to fetch the current ELD and state now, we can reduce the usage of unsol event of HDMI/DP pins. The unsol event isn't only unreliable, but it also needs the power up/down of the codec and link at each time, which is a significant power and time loss. In this patch, the jack creation and unsol/jack event handling are modified to use the audio component for the dedicated Intel chips. The jack handling got slightly more codes than a simple usage of hda_jack layer since we need to deal directly with snd_jack object; the hda_jack layer is basically designed for the pin sense read and unsol events, both of which aren't used any longer in our case. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 111 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 97 insertions(+), 14 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 2a7d29a07f31..e91a3223fe5f 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -83,6 +83,7 @@ struct hdmi_spec_per_pin { struct mutex lock; struct delayed_work work; struct snd_kcontrol *eld_ctl; + struct snd_jack *acomp_jack; /* jack via audio component */ int repoll_count; bool setup; /* the stream has been set up by prepare callback */ int channels; /* current number of channels */ @@ -1442,6 +1443,17 @@ static void intel_not_share_assigned_cvt(struct hda_codec *codec, } } +/* There is a fixed mapping between audio pin node and display port + * on current Intel platforms: + * Pin Widget 5 - PORT B (port = 1 in i915 driver) + * Pin Widget 6 - PORT C (port = 2 in i915 driver) + * Pin Widget 7 - PORT D (port = 3 in i915 driver) + */ +static int intel_pin2port(hda_nid_t pin_nid) +{ + return pin_nid - 4; +} + /* * HDA PCM callbacks */ @@ -1587,7 +1599,9 @@ static void update_eld(struct hda_codec *codec, &per_pin->eld_ctl->id); } -static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) +/* update ELD and jack state via HD-audio verbs */ +static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, + int repoll) { struct hda_jack_tbl *jack; struct hda_codec *codec = per_pin->codec; @@ -1650,6 +1664,56 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) return ret; } +/* update ELD and jack state via audio component */ +static void sync_eld_via_acomp(struct hda_codec *codec, + struct hdmi_spec_per_pin *per_pin) +{ + struct i915_audio_component *acomp = codec->bus->core.audio_component; + struct hdmi_spec *spec = codec->spec; + struct hdmi_eld *eld = &spec->temp_eld; + int size; + + if (acomp && acomp->ops && acomp->ops->get_eld) { + mutex_lock(&per_pin->lock); + size = acomp->ops->get_eld(acomp->dev, + intel_pin2port(per_pin->pin_nid), + &eld->monitor_present, + eld->eld_buffer, + ELD_MAX_SIZE); + if (size > 0) { + size = min(size, ELD_MAX_SIZE); + if (snd_hdmi_parse_eld(codec, &eld->info, + eld->eld_buffer, size) < 0) + size = -EINVAL; + } + + if (size > 0) { + eld->eld_valid = true; + eld->eld_size = size; + } else { + eld->eld_valid = false; + eld->eld_size = 0; + } + + update_eld(codec, per_pin, eld); + snd_jack_report(per_pin->acomp_jack, + eld->monitor_present ? SND_JACK_AVOUT : 0); + mutex_unlock(&per_pin->lock); + } +} + +static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) +{ + struct hda_codec *codec = per_pin->codec; + + if (codec_has_acomp(codec)) { + sync_eld_via_acomp(codec, per_pin); + return false; /* don't call snd_hda_jack_report_sync() */ + } else { + return hdmi_present_sense_via_verbs(per_pin, repoll); + } +} + static void hdmi_repoll_eld(struct work_struct *work) { struct hdmi_spec_per_pin *per_pin = @@ -1785,17 +1849,6 @@ static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) return non_pcm; } -/* There is a fixed mapping between audio pin node and display port - * on current Intel platforms: - * Pin Widget 5 - PORT B (port = 1 in i915 driver) - * Pin Widget 6 - PORT C (port = 2 in i915 driver) - * Pin Widget 7 - PORT D (port = 3 in i915 driver) - */ -static int intel_pin2port(hda_nid_t pin_nid) -{ - return pin_nid - 4; -} - /* * HDMI callbacks */ @@ -2100,6 +2153,30 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) return 0; } +static void free_acomp_jack_priv(struct snd_jack *jack) +{ + struct hdmi_spec_per_pin *per_pin = jack->private_data; + + per_pin->acomp_jack = NULL; +} + +static int add_acomp_jack_kctl(struct hda_codec *codec, + struct hdmi_spec_per_pin *per_pin, + const char *name) +{ + struct snd_jack *jack; + int err; + + err = snd_jack_new(codec->card, name, SND_JACK_AVOUT, &jack, + true, false); + if (err < 0) + return err; + per_pin->acomp_jack = jack; + jack->private_data = per_pin; + jack->private_free = free_acomp_jack_priv; + return 0; +} + static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) { char hdmi_str[32] = "HDMI/DP"; @@ -2110,6 +2187,8 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) if (pcmdev > 0) sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev); + if (codec_has_acomp(codec)) + return add_acomp_jack_kctl(codec, per_pin, hdmi_str); phantom_jack = !is_jack_detectable(codec, per_pin->pin_nid); if (phantom_jack) strncat(hdmi_str, " Phantom", @@ -2205,8 +2284,10 @@ static int generic_hdmi_init(struct hda_codec *codec) hda_nid_t pin_nid = per_pin->pin_nid; hdmi_init_pin(codec, pin_nid); - snd_hda_jack_detect_enable_callback(codec, pin_nid, - codec->jackpoll_interval > 0 ? jack_callback : NULL); + if (!codec_has_acomp(codec)) + snd_hda_jack_detect_enable_callback(codec, pin_nid, + codec->jackpoll_interval > 0 ? + jack_callback : NULL); } return 0; } @@ -2236,6 +2317,8 @@ static void generic_hdmi_free(struct hda_codec *codec) cancel_delayed_work_sync(&per_pin->work); eld_proc_free(per_pin); + if (per_pin->acomp_jack) + snd_device_free(codec->card, per_pin->acomp_jack); } if (spec->i915_bound) -- cgit 1.4.1 From e2dc7d7d8ed3019f72855af1c3dcda3fb456b488 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 1 Dec 2015 12:39:38 +0100 Subject: ALSA: hda - Move audio component accesses to hdac_i915.c A couple of i915_audio_component ops have been added and accessed directly from patch_hdmi.c. Ideally all these should be factored out into hdac_i915.c. This patch does it, adds two new helper functions for setting N/CTS and fetching ELD bytes. One bonus is that the hackish widget vs port mapping is also moved to hdac_i915.c, so that it can be fixed / enhanced more cleanly. Reviewed-by: Vinod Koul Signed-off-by: Takashi Iwai --- include/sound/hda_i915.h | 14 ++++++++++ sound/hda/hdac_i915.c | 66 ++++++++++++++++++++++++++++++++++++++++++++ sound/pci/hda/patch_hdmi.c | 69 +++++++++++++++++----------------------------- 3 files changed, 106 insertions(+), 43 deletions(-) (limited to 'sound/pci') diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h index 930b41e5acf4..fa341fcb5829 100644 --- a/include/sound/hda_i915.h +++ b/include/sound/hda_i915.h @@ -10,6 +10,9 @@ int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable); int snd_hdac_display_power(struct hdac_bus *bus, bool enable); int snd_hdac_get_display_clk(struct hdac_bus *bus); +int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate); +int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid, + bool *audio_enabled, char *buffer, int max_bytes); int snd_hdac_i915_init(struct hdac_bus *bus); int snd_hdac_i915_exit(struct hdac_bus *bus); int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *); @@ -26,6 +29,17 @@ static inline int snd_hdac_get_display_clk(struct hdac_bus *bus) { return 0; } +static inline int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, + int rate) +{ + return 0; +} +static inline int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid, + bool *audio_enabled, char *buffer, + int max_bytes) +{ + return -ENODEV; +} static inline int snd_hdac_i915_init(struct hdac_bus *bus) { return -ENODEV; diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index 8fef1b8d1fd8..c50177fb469f 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -118,6 +118,72 @@ int snd_hdac_get_display_clk(struct hdac_bus *bus) } EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk); +/* There is a fixed mapping between audio pin node and display port + * on current Intel platforms: + * Pin Widget 5 - PORT B (port = 1 in i915 driver) + * Pin Widget 6 - PORT C (port = 2 in i915 driver) + * Pin Widget 7 - PORT D (port = 3 in i915 driver) + */ +static int pin2port(hda_nid_t pin_nid) +{ + return pin_nid - 4; +} + +/** + * snd_hdac_sync_audio_rate - Set N/CTS based on the sample rate + * @bus: HDA core bus + * @nid: the pin widget NID + * @rate: the sample rate to set + * + * This function is supposed to be used only by a HD-audio controller + * driver that needs the interaction with i915 graphics. + * + * This function sets N/CTS value based on the given sample rate. + * Returns zero for success, or a negative error code. + */ +int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate) +{ + struct i915_audio_component *acomp = bus->audio_component; + + if (!acomp || !acomp->ops || !acomp->ops->sync_audio_rate) + return -ENODEV; + return acomp->ops->sync_audio_rate(acomp->dev, pin2port(nid), rate); +} +EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate); + +/** + * snd_hdac_acomp_get_eld - Get the audio state and ELD via component + * @bus: HDA core bus + * @nid: the pin widget NID + * @audio_enabled: the pointer to store the current audio state + * @buffer: the buffer pointer to store ELD bytes + * @max_bytes: the max bytes to be stored on @buffer + * + * This function is supposed to be used only by a HD-audio controller + * driver that needs the interaction with i915 graphics. + * + * This function queries the current state of the audio on the given + * digital port and fetches the ELD bytes onto the given buffer. + * It returns the number of bytes for the total ELD data, zero for + * invalid ELD, or a negative error code. + * + * The return size is the total bytes required for the whole ELD bytes, + * thus it may be over @max_bytes. If it's over @max_bytes, it implies + * that only a part of ELD bytes have been fetched. + */ +int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid, + bool *audio_enabled, char *buffer, int max_bytes) +{ + struct i915_audio_component *acomp = bus->audio_component; + + if (!acomp || !acomp->ops || !acomp->ops->get_eld) + return -ENODEV; + + return acomp->ops->get_eld(acomp->dev, pin2port(nid), audio_enabled, + buffer, max_bytes); +} +EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld); + static int hdac_component_master_bind(struct device *dev) { struct i915_audio_component *acomp = hdac_acomp; diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index e91a3223fe5f..cd9b0ffc91dc 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1443,17 +1443,6 @@ static void intel_not_share_assigned_cvt(struct hda_codec *codec, } } -/* There is a fixed mapping between audio pin node and display port - * on current Intel platforms: - * Pin Widget 5 - PORT B (port = 1 in i915 driver) - * Pin Widget 6 - PORT C (port = 2 in i915 driver) - * Pin Widget 7 - PORT D (port = 3 in i915 driver) - */ -static int intel_pin2port(hda_nid_t pin_nid) -{ - return pin_nid - 4; -} - /* * HDA PCM callbacks */ @@ -1668,38 +1657,36 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, static void sync_eld_via_acomp(struct hda_codec *codec, struct hdmi_spec_per_pin *per_pin) { - struct i915_audio_component *acomp = codec->bus->core.audio_component; struct hdmi_spec *spec = codec->spec; struct hdmi_eld *eld = &spec->temp_eld; int size; - if (acomp && acomp->ops && acomp->ops->get_eld) { - mutex_lock(&per_pin->lock); - size = acomp->ops->get_eld(acomp->dev, - intel_pin2port(per_pin->pin_nid), - &eld->monitor_present, - eld->eld_buffer, - ELD_MAX_SIZE); - if (size > 0) { - size = min(size, ELD_MAX_SIZE); - if (snd_hdmi_parse_eld(codec, &eld->info, - eld->eld_buffer, size) < 0) - size = -EINVAL; - } - - if (size > 0) { - eld->eld_valid = true; - eld->eld_size = size; - } else { - eld->eld_valid = false; - eld->eld_size = 0; - } - - update_eld(codec, per_pin, eld); - snd_jack_report(per_pin->acomp_jack, - eld->monitor_present ? SND_JACK_AVOUT : 0); - mutex_unlock(&per_pin->lock); + mutex_lock(&per_pin->lock); + size = snd_hdac_acomp_get_eld(&codec->bus->core, per_pin->pin_nid, + &eld->monitor_present, eld->eld_buffer, + ELD_MAX_SIZE); + if (size < 0) + goto unlock; + if (size > 0) { + size = min(size, ELD_MAX_SIZE); + if (snd_hdmi_parse_eld(codec, &eld->info, + eld->eld_buffer, size) < 0) + size = -EINVAL; + } + + if (size > 0) { + eld->eld_valid = true; + eld->eld_size = size; + } else { + eld->eld_valid = false; + eld->eld_size = 0; } + + update_eld(codec, per_pin, eld); + snd_jack_report(per_pin->acomp_jack, + eld->monitor_present ? SND_JACK_AVOUT : 0); + unlock: + mutex_unlock(&per_pin->lock); } static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) @@ -1865,7 +1852,6 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); hda_nid_t pin_nid = per_pin->pin_nid; struct snd_pcm_runtime *runtime = substream->runtime; - struct i915_audio_component *acomp = codec->bus->core.audio_component; bool non_pcm; int pinctl; @@ -1884,10 +1870,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, /* Call sync_audio_rate to set the N/CTS/M manually if necessary */ /* Todo: add DP1.2 MST audio support later */ - if (acomp && acomp->ops && acomp->ops->sync_audio_rate) - acomp->ops->sync_audio_rate(acomp->dev, - intel_pin2port(pin_nid), - runtime->rate); + snd_hdac_sync_audio_rate(&codec->bus->core, pin_nid, runtime->rate); non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); mutex_lock(&per_pin->lock); -- cgit 1.4.1 From 4f0189be3d0b2ba7f23b46295e4063fa3298aa74 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 10 Dec 2015 16:44:08 +0100 Subject: ALSA: hda - Clean up the code to check bdl_pos_adj option Just a minor cleanup; instead of passing an array, pass the assigned bdl_pos_adj option value directory in struct azx. Also split the code to get the default bdl_pos_adj value for the change that will follow after this. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_controller.c | 3 +-- sound/pci/hda/hda_controller.h | 2 +- sound/pci/hda/hda_intel.c | 29 ++++++++++++++++------------- 3 files changed, 18 insertions(+), 16 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 22dbfa563919..10c77074b4dc 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -1050,8 +1050,7 @@ int azx_bus_init(struct azx *chip, const char *model, if (chip->get_position[0] != azx_get_pos_lpib || chip->get_position[1] != azx_get_pos_lpib) bus->core.use_posbuf = true; - if (chip->bdl_pos_adj) - bus->core.bdl_pos_adj = chip->bdl_pos_adj[chip->dev_index]; + bus->core.bdl_pos_adj = chip->bdl_pos_adj; if (chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR) bus->core.corbrp_self_clear = true; diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index c1d28a657f19..a32ec9004edd 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -147,7 +147,7 @@ struct azx { #endif /* flags */ - const int *bdl_pos_adj; + int bdl_pos_adj; int poll_count; unsigned int running:1; unsigned int single_cmd:1; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index fe9bef339cea..a17bf0467edc 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -632,7 +632,7 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) if (wallclk < (azx_dev->core.period_wallclk * 5) / 4 && pos % azx_dev->core.period_bytes > azx_dev->core.period_bytes / 2) /* NG - it's below the first next period boundary */ - return chip->bdl_pos_adj[chip->dev_index] ? 0 : -1; + return chip->bdl_pos_adj ? 0 : -1; azx_dev->core.start_wallclk += wallclk; return 1; /* OK, it's fine */ } @@ -1488,6 +1488,17 @@ static void azx_probe_work(struct work_struct *work) azx_probe_continue(&hda->chip); } +static int default_bdl_pos_adj(struct azx *chip) +{ + switch (chip->driver_type) { + case AZX_DRIVER_ICH: + case AZX_DRIVER_PCH: + return 1; + default: + return 32; + } +} + /* * constructor */ @@ -1541,18 +1552,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, chip->single_cmd = single_cmd; azx_check_snoop_available(chip); - if (bdl_pos_adj[dev] < 0) { - switch (chip->driver_type) { - case AZX_DRIVER_ICH: - case AZX_DRIVER_PCH: - bdl_pos_adj[dev] = 1; - break; - default: - bdl_pos_adj[dev] = 32; - break; - } - } - chip->bdl_pos_adj = bdl_pos_adj; + if (bdl_pos_adj[dev] < 0) + chip->bdl_pos_adj = default_bdl_pos_adj(chip); + else + chip->bdl_pos_adj = bdl_pos_adj[dev]; err = azx_bus_init(chip, model[dev], &pci_hda_io_ops); if (err < 0) { -- cgit 1.4.1 From 2cf721db4b78c11cb57d5a30888eb25ca04d9a29 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 10 Dec 2015 16:49:36 +0100 Subject: ALSA: hda - Increase default bdl_pos_adj for Baytrail/Braswell Intel Atom processors seem to have a problem at recording when bdl_pos_adj is set to an odd value. When a value like 1 is used, it may drop the samples unexpectedly. Actually, for the old Atoms, we used to set AZX_DRIVER_SCH type, and this assigns 32 as default. Meanwhile the newer chips, Baytrail and Braswell, are set as AZX_DRIVER_PCH, and the lower default value, 1, is assigned. This patch changes the default values for these chipsets to a safer default, 32, again. Since changing the driver type (AZX_DRIVER_XXX) leads to the rename of the driver string, it would result in a possible regression. So, we can't change the type. Instead, in this patch, manual (ugly) PCI ID checks are added on top. A drawback by this increase is the slight increase of the latency, but it's a sub-ms order in normal situations, so mostly negligible. Reported-and-tested-by: Jochen Henneberg Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index a17bf0467edc..56ef6b6fb546 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1490,6 +1490,15 @@ static void azx_probe_work(struct work_struct *work) static int default_bdl_pos_adj(struct azx *chip) { + /* some exceptions: Atoms seem problematic with value 1 */ + if (chip->pci->vendor == PCI_VENDOR_ID_INTEL) { + switch (chip->pci->device) { + case 0x0f04: /* Baytrail */ + case 0x2284: /* Braswell */ + return 32; + } + } + switch (chip->driver_type) { case AZX_DRIVER_ICH: case AZX_DRIVER_PCH: -- cgit 1.4.1 From ef85f299c74e6c5dd98ec0230183be33f4c2813d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Dec 2015 08:12:37 +0100 Subject: ALSA: hda - Merge RIRB_PRE_DELAY into CTX_WORKAROUND caps AZX_DCAPS_RIRB_PRE_DELAY is always tied with AZX_DCAPS_CTX_WORKAROUND, which is Creative's XFi specific. So, we can replace it and reduce one more bit free for DCAPS. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_controller.c | 2 +- sound/pci/hda/hda_controller.h | 2 +- sound/pci/hda/hda_intel.c | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 10c77074b4dc..34022a36e5c5 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -956,7 +956,7 @@ irqreturn_t azx_interrupt(int irq, void *dev_id) status = azx_readb(chip, RIRBSTS); if (status & RIRB_INT_MASK) { if (status & RIRB_INT_RESPONSE) { - if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY) + if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) udelay(80); snd_hdac_bus_update_rirb(bus); } diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index a32ec9004edd..c723bcc7fcef 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -33,7 +33,7 @@ #define AZX_DCAPS_SNOOP_MASK (3 << 10) /* snoop type mask */ #define AZX_DCAPS_SNOOP_OFF (1 << 12) /* snoop default off */ #define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */ -#define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14) /* Put a delay before read */ +/* 14 unused */ #define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ #define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */ #define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 56ef6b6fb546..2d2f14830df7 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2314,14 +2314,12 @@ static const struct pci_device_id azx_ids[] = { .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class_mask = 0xffffff, .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | - AZX_DCAPS_NO_64BIT | - AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, + AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB }, #else /* this entry seems still valid -- i.e. without emu20kx chip */ { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | - AZX_DCAPS_NO_64BIT | - AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, + AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB }, #endif /* CM8888 */ { PCI_DEVICE(0x13f6, 0x5011), -- cgit 1.4.1 From 7d9a180895ee8c301df7f9447429009795c56c21 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Dec 2015 08:23:39 +0100 Subject: ALSA: hda - Raise AZX_DCAPS_RIRB_DELAY handling into top drivers AZX_DCAPS_RIRB_DELAY is dedicated only for Nvidia and its purpose is just to set a flag in bus. So it's better to be set in the toplevel driver, either hda_intel.c or hda_tegra.c, instead of the common hda_controller.c. This also allows us to strip this flag from dcaps, so save one more bit there. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_controller.c | 5 ----- sound/pci/hda/hda_controller.h | 2 +- sound/pci/hda/hda_intel.c | 7 ++++++- sound/pci/hda/hda_tegra.c | 5 +++-- 4 files changed, 10 insertions(+), 9 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 34022a36e5c5..37cf9cee9835 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -1054,11 +1054,6 @@ int azx_bus_init(struct azx *chip, const char *model, if (chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR) bus->core.corbrp_self_clear = true; - if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) { - dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n"); - bus->needs_damn_long_delay = 1; - } - if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) bus->core.align_bdle_4k = true; diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index c723bcc7fcef..65401372a7c8 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -32,7 +32,7 @@ #define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */ #define AZX_DCAPS_SNOOP_MASK (3 << 10) /* snoop type mask */ #define AZX_DCAPS_SNOOP_OFF (1 << 12) /* snoop default off */ -#define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */ +/* 13 unused */ /* 14 unused */ #define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ #define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 2d2f14830df7..bcb526103ecb 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -338,7 +338,7 @@ enum { /* quirks for Nvidia */ #define AZX_DCAPS_PRESET_NVIDIA \ - (AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \ + (AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \ AZX_DCAPS_NO_64BIT | AZX_DCAPS_CORBRP_SELF_CLEAR |\ AZX_DCAPS_SNOOP_TYPE(NVIDIA)) @@ -1573,6 +1573,11 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, return err; } + if (chip->driver_type == AZX_DRIVER_NVIDIA) { + dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n"); + chip->bus.needs_damn_long_delay = 1; + } + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); if (err < 0) { dev_err(card->dev, "Error creating device [card]!\n"); diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c index 58c0aad37284..17fd81736d3d 100644 --- a/sound/pci/hda/hda_tegra.c +++ b/sound/pci/hda/hda_tegra.c @@ -464,6 +464,8 @@ static int hda_tegra_create(struct snd_card *card, if (err < 0) return err; + chip->bus.needs_damn_long_delay = 1; + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); if (err < 0) { dev_err(card->dev, "Error creating device\n"); @@ -481,8 +483,7 @@ MODULE_DEVICE_TABLE(of, hda_tegra_match); static int hda_tegra_probe(struct platform_device *pdev) { - const unsigned int driver_flags = AZX_DCAPS_RIRB_DELAY | - AZX_DCAPS_CORBRP_SELF_CLEAR; + const unsigned int driver_flags = AZX_DCAPS_CORBRP_SELF_CLEAR; struct snd_card *card; struct azx *chip; struct hda_tegra *hda; -- cgit 1.4.1 From 26f0571781da98ea996c0cd7e03b733055b70f1f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Dec 2015 08:29:53 +0100 Subject: ALSA: hda - Drop AZX_DCAPS_POSFIX_VIA bit AZX_DCAPS_POSFIX_VIA is coupled always with AZX_DRIVER_VIA type, so we don't have to keep this bit in dcaps. Save one more! Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_controller.h | 2 +- sound/pci/hda/hda_intel.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index 65401372a7c8..a288ac1b5451 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -36,7 +36,7 @@ /* 14 unused */ #define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ #define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */ -#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */ +/* 17 unused */ #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index bcb526103ecb..67e672a77576 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1325,7 +1325,7 @@ static int check_position_fix(struct azx *chip, int fix) } /* Check VIA/ATI HD Audio Controller exist */ - if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) { + if (chip->driver_type == AZX_DRIVER_VIA) { dev_dbg(chip->card->dev, "Using VIACOMBO position fix\n"); return POS_FIX_VIACOMBO; } @@ -2284,8 +2284,7 @@ static const struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x1002, 0xaae8), .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, /* VIA VT8251/VT8237A */ - { PCI_DEVICE(0x1106, 0x3288), - .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, + { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA }, /* VIA GFX VT7122/VX900 */ { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC }, /* VIA GFX VT6122/VX11 */ -- cgit 1.4.1 From bcb337d166044cf389d3b9d3e6063c1ec4ca685d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Dec 2015 08:31:45 +0100 Subject: ALSA: hda - Drop unused AZX_DCAPS_REVERSE_ASSIGN AZX_DCAPS_REVERSE_ASSIGN is no longer referred by any code. Let's drop it. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_controller.h | 2 +- sound/pci/hda/hda_intel.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index a288ac1b5451..ec63bbf1ec6d 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -43,7 +43,7 @@ #define AZX_DCAPS_NO_ALIGN_BUFSIZE (1 << 21) /* no buffer size alignment */ /* 22 unused */ #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ -#define AZX_DCAPS_REVERSE_ASSIGN (1 << 24) /* Assign devices in reverse order */ +/* 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 diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 67e672a77576..1465f6a0e010 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -286,7 +286,7 @@ enum { /* quirks for Intel PCH */ #define AZX_DCAPS_INTEL_PCH_BASE \ (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\ - AZX_DCAPS_REVERSE_ASSIGN | AZX_DCAPS_SNOOP_TYPE(SCH)) + AZX_DCAPS_SNOOP_TYPE(SCH)) /* PCH up to IVB; no runtime PM */ #define AZX_DCAPS_INTEL_PCH_NOPM \ -- cgit 1.4.1 From e97e98c63b43040732ad5d1f0b38ad4a8371c73a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 18 Dec 2015 21:14:10 +0200 Subject: ALSA: fm801: explicitly free IRQ line Otherwise we will have a warning on ->remove() since device is a PCI one. WARNING: CPU: 4 PID: 1411 at /home/andy/prj/linux/fs/proc/generic.c:575 remove_proc_entry+0x137/0x160() remove_proc_entry: removing non-empty directory 'irq/21', leaking at least 'snd_fm801' Fixes: 5618955c4269 (ALSA: fm801: move to pcim_* and devm_* functions) Signed-off-by: Andy Shevchenko Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 1fdd92b6f18f..f57847cc53c1 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1165,6 +1165,8 @@ static int snd_fm801_free(struct fm801 *chip) cmdw |= 0x00c3; fm801_writew(chip, IRQ_MASK, cmdw); + devm_free_irq(&chip->pci->dev, chip->irq, chip); + __end_hw: #ifdef CONFIG_SND_FM801_TEA575X_BOOL if (!(chip->tea575x_tuner & TUNER_DISABLED)) { -- cgit 1.4.1 From 4b5c15f746db70efc710369f62c6e1d323e20fb9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 18 Dec 2015 21:14:11 +0200 Subject: ALSA: fm801: convert rest outw() / inw() to use helpers The patch introduces two new helpers fm801_iowrite16() and fm801_ioread16() to write and read the registers by offset. Previously similar was done to access the hardware registers by their names. Signed-off-by: Andy Shevchenko Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index f57847cc53c1..c2afb41907bd 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -212,6 +212,20 @@ struct fm801 { #endif }; +/* + * IO accessors + */ + +static inline void fm801_iowrite16(struct fm801 *chip, unsigned short offset, u16 value) +{ + outw(value, chip->port + offset); +} + +static inline u16 fm801_ioread16(struct fm801 *chip, unsigned short offset) +{ + return inw(chip->port + offset); +} + static const struct pci_device_id snd_fm801_ids[] = { { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */ { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */ @@ -256,11 +270,11 @@ static int snd_fm801_update_bits(struct fm801 *chip, unsigned short reg, unsigned short old, new; spin_lock_irqsave(&chip->reg_lock, flags); - old = inw(chip->port + reg); + old = fm801_ioread16(chip, reg); new = (old & ~mask) | value; change = old != new; if (change) - outw(new, chip->port + reg); + fm801_iowrite16(chip, reg, new); spin_unlock_irqrestore(&chip->reg_lock, flags); return change; } @@ -851,10 +865,11 @@ static int snd_fm801_get_single(struct snd_kcontrol *kcontrol, int shift = (kcontrol->private_value >> 8) & 0xff; int mask = (kcontrol->private_value >> 16) & 0xff; int invert = (kcontrol->private_value >> 24) & 0xff; + long *value = ucontrol->value.integer.value; - ucontrol->value.integer.value[0] = (inw(chip->port + reg) >> shift) & mask; + value[0] = (fm801_ioread16(chip, reg) >> shift) & mask; if (invert) - ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; + value[0] = mask - value[0]; return 0; } @@ -907,14 +922,15 @@ static int snd_fm801_get_double(struct snd_kcontrol *kcontrol, int shift_right = (kcontrol->private_value >> 12) & 0x0f; int mask = (kcontrol->private_value >> 16) & 0xff; int invert = (kcontrol->private_value >> 24) & 0xff; + long *value = ucontrol->value.integer.value; spin_lock_irq(&chip->reg_lock); - ucontrol->value.integer.value[0] = (inw(chip->port + reg) >> shift_left) & mask; - ucontrol->value.integer.value[1] = (inw(chip->port + reg) >> shift_right) & mask; + value[0] = (fm801_ioread16(chip, reg) >> shift_left) & mask; + value[1] = (fm801_ioread16(chip, reg) >> shift_right) & mask; spin_unlock_irq(&chip->reg_lock); if (invert) { - ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; - ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; + value[0] = mask - value[0]; + value[1] = mask - value[1]; } return 0; } @@ -1372,7 +1388,7 @@ static int snd_fm801_suspend(struct device *dev) snd_ac97_suspend(chip->ac97); snd_ac97_suspend(chip->ac97_sec); for (i = 0; i < ARRAY_SIZE(saved_regs); i++) - chip->saved_regs[i] = inw(chip->port + saved_regs[i]); + chip->saved_regs[i] = fm801_ioread16(chip, saved_regs[i]); /* FIXME: tea575x suspend */ return 0; } @@ -1387,7 +1403,7 @@ static int snd_fm801_resume(struct device *dev) snd_ac97_resume(chip->ac97); snd_ac97_resume(chip->ac97_sec); for (i = 0; i < ARRAY_SIZE(saved_regs); i++) - outw(chip->saved_regs[i], chip->port + saved_regs[i]); + fm801_iowrite16(chip, saved_regs[i], chip->saved_regs[i]); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; -- cgit 1.4.1 From 997c87dad2a322516db391c7df440bd89e18fc31 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 18 Dec 2015 21:14:12 +0200 Subject: ALSA: fm801: put curly braces around empty if-body MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compiler complains on unused condition as follows sound/pci/fm801.c: In function ‘snd_fm801_interrupt’: sound/pci/fm801.c:585:3: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body] Put the curly braces around empty body as suggested. Signed-off-by: Andy Shevchenko Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index c2afb41907bd..c24cb04895b8 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -592,8 +592,9 @@ static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id) } if (chip->rmidi && (status & FM801_IRQ_MPU)) snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); - if (status & FM801_IRQ_VOLUME) - ;/* TODO */ + if (status & FM801_IRQ_VOLUME) { + /* TODO */ + } return IRQ_HANDLED; } -- cgit 1.4.1 From d3d33aabac51341065bcce0e9c2d9d27902a08c4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 18 Dec 2015 21:14:13 +0200 Subject: ALSA: fm801: store struct device instead of pci_dev There is no need to store struct pci_dev in struct fm801. Generic struct device can be easily translated to struct pci_dev whenever it's needed, in particular for one user for now. Signed-off-by: Andy Shevchenko Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index c24cb04895b8..e4e610c5d1ba 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -163,6 +163,7 @@ MODULE_PARM_DESC(radio_nr, "Radio device numbers"); * @cap_ctrl: capture control */ struct fm801 { + struct device *dev; int irq; unsigned long port; @@ -190,7 +191,6 @@ struct fm801 { struct snd_ac97 *ac97; struct snd_ac97 *ac97_sec; - struct pci_dev *pci; struct snd_card *card; struct snd_pcm *pcm; struct snd_rawmidi *rmidi; @@ -715,6 +715,7 @@ static struct snd_pcm_ops snd_fm801_capture_ops = { static int snd_fm801_pcm(struct fm801 *chip, int device) { + struct pci_dev *pdev = to_pci_dev(chip->dev); struct snd_pcm *pcm; int err; @@ -730,7 +731,7 @@ static int snd_fm801_pcm(struct fm801 *chip, int device) chip->pcm = pcm; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->pci), + snd_dma_pci_data(pdev), chip->multichannel ? 128*1024 : 64*1024, 128*1024); return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, @@ -1182,7 +1183,7 @@ static int snd_fm801_free(struct fm801 *chip) cmdw |= 0x00c3; fm801_writew(chip, IRQ_MASK, cmdw); - devm_free_irq(&chip->pci->dev, chip->irq, chip); + devm_free_irq(chip->dev, chip->irq, chip); __end_hw: #ifdef CONFIG_SND_FM801_TEA575X_BOOL @@ -1220,7 +1221,7 @@ static int snd_fm801_create(struct snd_card *card, return -ENOMEM; spin_lock_init(&chip->reg_lock); chip->card = card; - chip->pci = pci; + chip->dev = &pci->dev; chip->irq = -1; chip->tea575x_tuner = tea575x_tuner; if ((err = pci_request_regions(pci, "FM801")) < 0) -- cgit 1.4.1 From dbec6719ac036f68568d8488805d41346c021eff Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 21 Dec 2015 19:09:52 +0200 Subject: ALSA: fm801: propagate TUNER_ONLY bit when autodetected The commit d7ba858a7f7a (ALSA: fm801: implement TEA575x tuner autodetection) brings autodetection to the driver. However the autodetection algorithm misses the TUNER_ONLY bit if it is supplied by the user. Thus, user gets weird messages and no card registered. snd_fm801 0000:0d:01.0: detected TEA575x radio type SF64-PCR snd_fm801 0000:0d:01.0: AC'97 interface is busy (1) snd_fm801 0000:0d:01.0: AC'97 interface is busy (1) ... snd_fm801 0000:0d:01.0: AC'97 0 does not respond - RESET snd_fm801 0000:0d:01.0: AC'97 interface is busy (1) snd_fm801 0000:0d:01.0: AC'97 interface is busy (1) snd_fm801 0000:0d:01.0: AC'97 0 access is not valid [0x0], removing mixer. snd_fm801: probe of 0000:0d:01.0 failed with error -5 Do a copy of TUNER_ONLY bit to be applied after autodetection is done. Fixes: d7ba858a7f7a (ALSA: fm801: implement TEA575x tuner autodetection) Signed-off-by: Andy Shevchenko Cc: Ondrej Zary Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index e4e610c5d1ba..63025b8925f5 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1269,6 +1269,8 @@ static int snd_fm801_create(struct snd_card *card, return -ENODEV; } } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) { + unsigned int tuner_only = tea575x_tuner & TUNER_ONLY; + /* autodetect tuner connection */ for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { chip->tea575x_tuner = tea575x_tuner; @@ -1283,6 +1285,8 @@ static int snd_fm801_create(struct snd_card *card, dev_err(card->dev, "TEA575x radio not found\n"); chip->tea575x_tuner = TUNER_DISABLED; } + + chip->tea575x_tuner |= tuner_only; } if (!(chip->tea575x_tuner & TUNER_DISABLED)) { strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name, -- cgit 1.4.1 From b56fa687e02b27f8bd9d282950a88c2ed23d766b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 21 Dec 2015 19:09:53 +0200 Subject: ALSA: fm801: detect FM-only card earlier If user does not supply tea575x_tuner parameter the driver tries to detect the tuner type. The failed codec initialization is considered as FM-only card present, however the driver still registers an IRQ handler for it. Move codec detection earlier to set tea575x_tuner parameter before check. Here the following functions are introduced reset_coded() resets AC97 codec snd_fm801_chip_multichannel_init() initializes cards with multichannel support Fixes: 5618955c4269 (ALSA: fm801: move to pcim_* and devm_* functions) Signed-off-by: Andy Shevchenko Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 69 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 30 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 63025b8925f5..294fc131aee0 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1098,26 +1098,20 @@ static int wait_for_codec(struct fm801 *chip, unsigned int codec_id, return -EIO; } -static int snd_fm801_chip_init(struct fm801 *chip, int resume) +static int reset_codec(struct fm801 *chip) { - unsigned short cmdw; - - if (chip->tea575x_tuner & TUNER_ONLY) - goto __ac97_ok; - /* codec cold reset + AC'97 warm reset */ fm801_writew(chip, CODEC_CTRL, (1 << 5) | (1 << 6)); fm801_readw(chip, CODEC_CTRL); /* flush posting data */ udelay(100); fm801_writew(chip, CODEC_CTRL, 0); - if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0) - if (!resume) { - dev_info(chip->card->dev, - "Primary AC'97 codec not found, assume SF64-PCR (tuner-only)\n"); - chip->tea575x_tuner = 3 | TUNER_ONLY; - goto __ac97_ok; - } + return wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)); +} + +static void snd_fm801_chip_multichannel_init(struct fm801 *chip) +{ + unsigned short cmdw; if (chip->multichannel) { if (chip->secondary_addr) { @@ -1144,8 +1138,11 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume) /* cause timeout problems */ wait_for_codec(chip, 0, AC97_VENDOR_ID1, msecs_to_jiffies(750)); } +} - __ac97_ok: +static void snd_fm801_chip_init(struct fm801 *chip) +{ + unsigned short cmdw; /* init volume */ fm801_writew(chip, PCM_VOL, 0x0808); @@ -1166,11 +1163,8 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume) /* interrupt clear */ fm801_writew(chip, IRQ_STATUS, FM801_IRQ_PLAYBACK | FM801_IRQ_CAPTURE | FM801_IRQ_MPU); - - return 0; } - static int snd_fm801_free(struct fm801 *chip) { unsigned short cmdw; @@ -1227,7 +1221,23 @@ static int snd_fm801_create(struct snd_card *card, if ((err = pci_request_regions(pci, "FM801")) < 0) return err; chip->port = pci_resource_start(pci, 0); - if ((tea575x_tuner & TUNER_ONLY) == 0) { + + if (pci->revision >= 0xb1) /* FM801-AU */ + chip->multichannel = 1; + + if (!(chip->tea575x_tuner & TUNER_ONLY)) { + if (reset_codec(chip) < 0) { + dev_info(chip->card->dev, + "Primary AC'97 codec not found, assume SF64-PCR (tuner-only)\n"); + chip->tea575x_tuner = 3 | TUNER_ONLY; + } else { + snd_fm801_chip_multichannel_init(chip); + } + } + + snd_fm801_chip_init(chip); + + if ((chip->tea575x_tuner & TUNER_ONLY) == 0) { if (devm_request_irq(&pci->dev, pci->irq, snd_fm801_interrupt, IRQF_SHARED, KBUILD_MODNAME, chip)) { dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); @@ -1238,13 +1248,6 @@ static int snd_fm801_create(struct snd_card *card, pci_set_master(pci); } - if (pci->revision >= 0xb1) /* FM801-AU */ - chip->multichannel = 1; - - snd_fm801_chip_init(chip, 0); - /* init might set tuner access method */ - tea575x_tuner = chip->tea575x_tuner; - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { snd_fm801_free(chip); return err; @@ -1261,15 +1264,15 @@ static int snd_fm801_create(struct snd_card *card, chip->tea.private_data = chip; chip->tea.ops = &snd_fm801_tea_ops; sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); - if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && - (tea575x_tuner & TUNER_TYPE_MASK) < 4) { + if ((chip->tea575x_tuner & TUNER_TYPE_MASK) > 0 && + (chip->tea575x_tuner & TUNER_TYPE_MASK) < 4) { if (snd_tea575x_init(&chip->tea, THIS_MODULE)) { dev_err(card->dev, "TEA575x radio not found\n"); snd_fm801_free(chip); return -ENODEV; } - } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) { - unsigned int tuner_only = tea575x_tuner & TUNER_ONLY; + } else if ((chip->tea575x_tuner & TUNER_TYPE_MASK) == 0) { + unsigned int tuner_only = chip->tea575x_tuner & TUNER_ONLY; /* autodetect tuner connection */ for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { @@ -1405,7 +1408,13 @@ static int snd_fm801_resume(struct device *dev) struct fm801 *chip = card->private_data; int i; - snd_fm801_chip_init(chip, 1); + if (chip->tea575x_tuner & TUNER_ONLY) { + snd_fm801_chip_init(chip); + } else { + reset_codec(chip); + snd_fm801_chip_multichannel_init(chip); + snd_fm801_chip_init(chip); + } snd_ac97_resume(chip->ac97); snd_ac97_resume(chip->ac97_sec); for (i = 0; i < ARRAY_SIZE(saved_regs); i++) -- cgit 1.4.1 From 14da04b5ff8e1e70b53f9f927e915e32a56651e1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 21 Dec 2015 19:09:54 +0200 Subject: ALSA: fm801: no need to suspend absent codec In case of tuner only card there is no need to take care of the codec which is anyway absent. Signed-off-by: Andy Shevchenko Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 294fc131aee0..9e870884c02c 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1393,12 +1393,17 @@ static int snd_fm801_suspend(struct device *dev) int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); - snd_ac97_suspend(chip->ac97); - snd_ac97_suspend(chip->ac97_sec); + + if (chip->tea575x_tuner & TUNER_ONLY) { + /* FIXME: tea575x suspend */ + } else { + snd_pcm_suspend_all(chip->pcm); + snd_ac97_suspend(chip->ac97); + snd_ac97_suspend(chip->ac97_sec); + } + for (i = 0; i < ARRAY_SIZE(saved_regs); i++) chip->saved_regs[i] = fm801_ioread16(chip, saved_regs[i]); - /* FIXME: tea575x suspend */ return 0; } @@ -1414,9 +1419,10 @@ static int snd_fm801_resume(struct device *dev) reset_codec(chip); snd_fm801_chip_multichannel_init(chip); snd_fm801_chip_init(chip); + snd_ac97_resume(chip->ac97); + snd_ac97_resume(chip->ac97_sec); } - snd_ac97_resume(chip->ac97); - snd_ac97_resume(chip->ac97_sec); + for (i = 0; i < ARRAY_SIZE(saved_regs); i++) fm801_iowrite16(chip, saved_regs[i], chip->saved_regs[i]); -- cgit 1.4.1 From 37ba8fca7e42b6e689689217b9739e3a9a3c35e6 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 21 Dec 2015 19:09:55 +0200 Subject: ALSA: fm801: save context before suspend devices In symmetry we save context first before suspend and restore it last after resume. Signed-off-by: Andy Shevchenko Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 9e870884c02c..0b1ae6c684c1 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1394,6 +1394,9 @@ static int snd_fm801_suspend(struct device *dev) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + for (i = 0; i < ARRAY_SIZE(saved_regs); i++) + chip->saved_regs[i] = fm801_ioread16(chip, saved_regs[i]); + if (chip->tea575x_tuner & TUNER_ONLY) { /* FIXME: tea575x suspend */ } else { @@ -1402,8 +1405,6 @@ static int snd_fm801_suspend(struct device *dev) snd_ac97_suspend(chip->ac97_sec); } - for (i = 0; i < ARRAY_SIZE(saved_regs); i++) - chip->saved_regs[i] = fm801_ioread16(chip, saved_regs[i]); return 0; } -- cgit 1.4.1 From cb41f271d01b7c985ab47ea26fdef531a6237561 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 21 Dec 2015 19:09:56 +0200 Subject: ALSA: fm801: restore TEA575x state on resume The suspend / resume cycle resets the settings of the FM tuner. Restore frequency settings on resume. Signed-off-by: Andy Shevchenko Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 0b1ae6c684c1..161925b6518e 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1427,6 +1427,11 @@ static int snd_fm801_resume(struct device *dev) for (i = 0; i < ARRAY_SIZE(saved_regs); i++) fm801_iowrite16(chip, saved_regs[i], chip->saved_regs[i]); +#ifdef CONFIG_SND_FM801_TEA575X_BOOL + if (!(chip->tea575x_tuner & TUNER_DISABLED)) + snd_tea575x_set_freq(&chip->tea); +#endif + snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; } -- cgit 1.4.1 From 064e186f8fe7f5e1c59f74bc455ac3aa18efa503 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 30 Dec 2015 11:21:57 +0100 Subject: ALSA: atiixp: constify atiixp_dma_ops structures The atiixp_dma_ops structures are never modified, so declare them as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Takashi Iwai --- sound/pci/atiixp.c | 6 +++--- sound/pci/atiixp_modem.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 1028fc8bdff5..2ce0022dbc46 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -1219,7 +1219,7 @@ static struct ac97_pcm atiixp_pcm_defs[] = { }, }; -static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = { +static const struct atiixp_dma_ops snd_atiixp_playback_dma_ops = { .type = ATI_DMA_PLAYBACK, .llp_offset = ATI_REG_OUT_DMA_LINKPTR, .dt_cur = ATI_REG_OUT_DMA_DT_CUR, @@ -1228,7 +1228,7 @@ static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = { .flush_dma = atiixp_out_flush_dma, }; -static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = { +static const struct atiixp_dma_ops snd_atiixp_capture_dma_ops = { .type = ATI_DMA_CAPTURE, .llp_offset = ATI_REG_IN_DMA_LINKPTR, .dt_cur = ATI_REG_IN_DMA_DT_CUR, @@ -1237,7 +1237,7 @@ static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = { .flush_dma = atiixp_in_flush_dma, }; -static struct atiixp_dma_ops snd_atiixp_spdif_dma_ops = { +static const struct atiixp_dma_ops snd_atiixp_spdif_dma_ops = { .type = ATI_DMA_SPDIF, .llp_offset = ATI_REG_SPDF_DMA_LINKPTR, .dt_cur = ATI_REG_SPDF_DMA_DT_CUR, diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 27ed678a46df..c534552963e7 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -970,7 +970,7 @@ static struct snd_pcm_ops snd_atiixp_capture_ops = { .pointer = snd_atiixp_pcm_pointer, }; -static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = { +static const struct atiixp_dma_ops snd_atiixp_playback_dma_ops = { .type = ATI_DMA_PLAYBACK, .llp_offset = ATI_REG_MODEM_OUT_DMA1_LINKPTR, .dt_cur = ATI_REG_MODEM_OUT_DMA1_DT_CUR, @@ -979,7 +979,7 @@ static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = { .flush_dma = atiixp_out_flush_dma, }; -static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = { +static const struct atiixp_dma_ops snd_atiixp_capture_dma_ops = { .type = ATI_DMA_CAPTURE, .llp_offset = ATI_REG_MODEM_IN_DMA_LINKPTR, .dt_cur = ATI_REG_MODEM_IN_DMA_DT_CUR, -- cgit 1.4.1 From 55a8aeef6dbdb90f5ee97801b86c73ffd93e8afd Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 30 Dec 2015 11:44:53 +0100 Subject: ALSA: cs5535audio: constify cs5535audio_dma_ops structures The cs5535audio_dma_ops structures are never modified, so declare them as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Takashi Iwai --- sound/pci/cs5535audio/cs5535audio_pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index 9c2dc911d8d7..27fa57da8dc4 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c @@ -402,7 +402,7 @@ static struct snd_pcm_ops snd_cs5535audio_capture_ops = { .pointer = snd_cs5535audio_pcm_pointer, }; -static struct cs5535audio_dma_ops snd_cs5535audio_playback_dma_ops = { +static const struct cs5535audio_dma_ops snd_cs5535audio_playback_dma_ops = { .type = CS5535AUDIO_DMA_PLAYBACK, .enable_dma = cs5535audio_playback_enable_dma, .disable_dma = cs5535audio_playback_disable_dma, @@ -412,7 +412,7 @@ static struct cs5535audio_dma_ops snd_cs5535audio_playback_dma_ops = { .read_dma_pntr = cs5535audio_playback_read_dma_pntr, }; -static struct cs5535audio_dma_ops snd_cs5535audio_capture_dma_ops = { +static const struct cs5535audio_dma_ops snd_cs5535audio_capture_dma_ops = { .type = CS5535AUDIO_DMA_CAPTURE, .enable_dma = cs5535audio_capture_enable_dma, .disable_dma = cs5535audio_capture_disable_dma, -- cgit 1.4.1 From 56f27013482c0803d978b667fe85de04ce9357cd Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 11 Jan 2016 09:33:14 +0100 Subject: ALSA: hda - Fixup inverted internal mic for Lenovo E50-80 Inform userspace that one channel of the internal mic has reversed polarity, so it does not attempt to add both channels together and end up with silence. Cc: stable@vger.kernel.org Reported-by: Andrzej Mendel Alsa-info: http://www.alsa-project.org/db/?f=3088f82a0cf977855f92af9db8ad406c04f71efa BugLink: https://bugs.launchpad.net/bugs/1529624 Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3a89d82f8057..2fdda51d07c4 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4666,6 +4666,7 @@ enum { ALC290_FIXUP_SUBWOOFER, ALC290_FIXUP_SUBWOOFER_HSJACK, ALC269_FIXUP_THINKPAD_ACPI, + ALC269_FIXUP_DMIC_THINKPAD_ACPI, ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, ALC255_FIXUP_HEADSET_MODE, @@ -5103,6 +5104,12 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = hda_fixup_thinkpad_acpi, }, + [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_inv_dmic, + .chained = true, + .chain_id = ALC269_FIXUP_THINKPAD_ACPI, + }, [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -5457,6 +5464,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE), SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), + SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), -- cgit 1.4.1 From de65360be0239a63268de589c4189f8ee52dad6c Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 22 Dec 2015 19:09:05 +0100 Subject: ALSA: hda_intel: add card number to irq description Currently the info in /proc/interrupts doesn't allow to figure out which interrupt belongs to which card (HDMI, PCH, ..). Therefore add card details to the interrupt description. With the patch the info in /proc/interrupts looks like this: PCI-MSI 442368-edge snd_hda_intel:card1 PCI-MSI 49152-edge snd_hda_intel:card0 NOTE: this patch adds the new irq_descr field snd_card struct that is filled automatically at a card object creation. This can be used generically for other drivers as well. The changes for others will follow later -- tiwai Signed-off-by: Heiner Kallweit Signed-off-by: Takashi Iwai --- include/sound/core.h | 1 + sound/core/init.c | 3 +++ sound/pci/hda/hda_intel.c | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/include/sound/core.h b/include/sound/core.h index cdfecafff0f4..31079ea5e484 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -99,6 +99,7 @@ struct snd_card { char driver[16]; /* driver name */ char shortname[32]; /* short name of this soundcard */ char longname[80]; /* name of this soundcard */ + char irq_descr[32]; /* Interrupt description */ char mixername[80]; /* mixer name */ char components[128]; /* card components delimited with space */ diff --git a/sound/core/init.c b/sound/core/init.c index 20f37fb3800e..6bda8436d765 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -268,6 +268,9 @@ int snd_card_new(struct device *parent, int idx, const char *xid, if (err < 0) goto __error; + snprintf(card->irq_descr, sizeof(card->irq_descr), "%s:%s", + dev_driver_string(card->dev), dev_name(&card->card_dev)); + /* the control interface cannot be accessed from the user space until */ /* snd_cards_bitmask and snd_cards are set with snd_card_register */ err = snd_ctl_create(card); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 83800ac6ebd7..c0bef11afa7e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -725,7 +725,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect) if (request_irq(chip->pci->irq, azx_interrupt, chip->msi ? 0 : IRQF_SHARED, - KBUILD_MODNAME, chip)) { + chip->card->irq_descr, chip)) { dev_err(chip->card->dev, "unable to grab IRQ %d, disabling device\n", chip->pci->irq); -- cgit 1.4.1 From 98070576c4f77509459c83cd2358617ef0769a38 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 12 Jan 2016 21:06:39 +0100 Subject: ALSA: hda - Fix white noise on Dell Latitude E5550 Dell Latitude E5550 (1028:062c) has a white noise problem like other Latitude E models, and it gets fixed by the very same quirk as well. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=110591 Cc: # v4.1+ Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2fdda51d07c4..f0ed41e1a884 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5339,6 +5339,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), + SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X), SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X), SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), -- cgit 1.4.1 From 0a1f90a982e85f4921bed606a6b41a24f4de2ae1 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Wed, 13 Jan 2016 11:51:38 +0800 Subject: ALSA: hda - fix the headset mic detection problem for a Dell laptop The machine uses codec alc255, and the pin configuration value for pin 0x14 on this machine is 0x90171130 which is not in the pin quirk table yet. Cc: stable@vger.kernel.org BugLink: https://bugs.launchpad.net/bugs/1533461 Signed-off-by: Hui Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f0ed41e1a884..61d8502e6b08 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5624,6 +5624,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x12, 0x90a60170}, {0x14, 0x90170130}, {0x21, 0x02211040}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60170}, + {0x14, 0x90171130}, + {0x21, 0x02211040}), SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, {0x12, 0x90a60170}, {0x14, 0x90170140}, -- cgit 1.4.1 From 91815d8aa7e2f45d30e51caa297061ad893628d9 Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Thu, 14 Jan 2016 14:09:00 +0800 Subject: ALSA: hda - add codec support for Kabylake display audio codec This patch adds codec ID (0x8086280b) for Kabylake display codec and apply the hsw fix-ups to Kabylake. Signed-off-by: Libin Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index cd9b0ffc91dc..426a29a1c19b 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -51,8 +51,10 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); #define is_broadwell(codec) ((codec)->core.vendor_id == 0x80862808) #define is_skylake(codec) ((codec)->core.vendor_id == 0x80862809) #define is_broxton(codec) ((codec)->core.vendor_id == 0x8086280a) +#define is_kabylake(codec) ((codec)->core.vendor_id == 0x8086280b) #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \ - || is_skylake(codec) || is_broxton(codec)) + || is_skylake(codec) || is_broxton(codec) \ + || is_kabylake(codec)) #define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882) #define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883) @@ -3667,6 +3669,7 @@ HDA_CODEC_ENTRY(0x80862807, "Haswell HDMI", patch_generic_hdmi), HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI", patch_generic_hdmi), HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_generic_hdmi), HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_generic_hdmi), +HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_generic_hdmi), HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi), HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_generic_hdmi), HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_generic_hdmi), -- cgit 1.4.1 From cf52103a218744f3fd18111325c28e95aa9cd226 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 15 Jan 2016 12:59:25 +0100 Subject: ALSA: hda - Add fixup for Dell Latitidue E6540 Another Dell model, another fixup entry: Latitude E6540 needs the same fixup as other Latitude E series as workaround for noise problems. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=104341 Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 61d8502e6b08..8143c0e24a27 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5331,6 +5331,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X), + SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X), SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X), SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X), SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), -- cgit 1.4.1