Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e1f14a54 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "Usually we get a big collection of fixes for ASoC once during rc.  And
  this is it.

  At this time, most of fixes are about Intel Skylake ASoC driver, which
  is a new and still on-going development.  Along with it, a slight
  large LOC is seen in legacy HD-audio driver, but it's merely a code
  move to the upper layer.

  Other than that, the rest are small or trivial fixes to various
  drivers, in addition to an ASoC dapm debugfs code fix"

* tag 'sound-4.6-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (24 commits)
  ALSA: hda - Update BCLK also at hotplug for i915 HSW/BDW
  ALSA: hda - Add dock support for ThinkPad X260
  ASoC: wm5102: Free compressed IRQ in CODEC remove
  ASoC: arizona: Free speaker thermal IRQs in CODEC remove
  ASoC: Intel: Skylake: Fix ibs/obs calc for non-integral sampling rates
  ASoC: Intel: sst: fix a loop timeout in sst_hsw_stream_reset()
  ASoC: Intel: Skylake: Fix to turn OFF codec power when entering S3
  ASoC: hdac_hdmi: Fix codec power state in S3 during playback
  ASoC: hdac_hdmi: Fix to use dev_pm ops instead soc pm
  ASoC: wm8962: Correct typo when setting DSPCLK rate
  ASoC: nau8825: Fix jack detection across suspend
  ASoC: Intel: Skylake: Fix DSP resource de-allocation
  ASoC: Intel: Skylake: Fix for unloading module only when it is loaded
  ASoC: Intel: Skylake: Fix kbuild dependency
  ASoC: dapm: Make sure we have a card when displaying component widgets
  ASoC: rt5640: Correct the digital interface data select
  ASoC: Intel: Skylake: remove call to pci_dev_put
  ASoC: Intel: Skylake: Call i915 exit last
  ASoC: Intel: Skylake: Unmap the address last
  ASoC: Intel: Skylake: Freeup properly on skl_dsp_free
  ...
parents 6fa9bffb af9cc93c
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
#ifdef CONFIG_SND_HDA_I915
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);
void snd_hdac_i915_set_bclk(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);
@@ -25,9 +25,8 @@ static inline int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
{
	return 0;
}
static inline int snd_hdac_get_display_clk(struct hdac_bus *bus)
static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
{
	return 0;
}
static inline int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid,
					   int rate)
+2 −3
Original line number Diff line number Diff line
@@ -104,12 +104,11 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init_all);
 */
void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus)
{
	struct hdac_stream *s;
	struct hdac_stream *s, *_s;
	struct hdac_ext_stream *stream;
	struct hdac_bus *bus = ebus_to_hbus(ebus);

	while (!list_empty(&bus->stream_list)) {
		s = list_first_entry(&bus->stream_list, struct hdac_stream, list);
	list_for_each_entry_safe(s, _s, &bus->stream_list, list) {
		stream = stream_to_hdac_ext_stream(s);
		snd_hdac_ext_stream_decouple(ebus, stream, false);
		list_del(&s->list);
+51 −11
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <sound/core.h>
#include <sound/hdaudio.h>
#include <sound/hda_i915.h>
#include <sound/hda_register.h>

static struct i915_audio_component *hdac_acomp;

@@ -97,26 +98,65 @@ int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
}
EXPORT_SYMBOL_GPL(snd_hdac_display_power);

#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
				((pci)->device == 0x0c0c) || \
				((pci)->device == 0x0d0c) || \
				((pci)->device == 0x160c))

/**
 * snd_hdac_get_display_clk - Get CDCLK in kHz
 * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW
 * @bus: HDA core bus
 *
 * This function is supposed to be used only by a HD-audio controller
 * driver that needs the interaction with i915 graphics.
 * Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK
 * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value)
 * are used to convert CDClk (Core Display Clock) to 24MHz BCLK:
 * BCLK = CDCLK * M / N
 * The values will be lost when the display power well is disabled and need to
 * be restored to avoid abnormal playback speed.
 *
 * This function queries CDCLK value in kHz from the graphics driver and
 * returns the value.  A negative code is returned in error.
 * Call this function at initializing and changing power well, as well as
 * at ELD notifier for the hotplug.
 */
int snd_hdac_get_display_clk(struct hdac_bus *bus)
void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
{
	struct i915_audio_component *acomp = bus->audio_component;
	struct pci_dev *pci = to_pci_dev(bus->dev);
	int cdclk_freq;
	unsigned int bclk_m, bclk_n;

	if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq)
		return; /* only for i915 binding */
	if (!CONTROLLER_IN_GPU(pci))
		return; /* only HSW/BDW */

	cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev);
	switch (cdclk_freq) {
	case 337500:
		bclk_m = 16;
		bclk_n = 225;
		break;

	case 450000:
	default: /* default CDCLK 450MHz */
		bclk_m = 4;
		bclk_n = 75;
		break;

	case 540000:
		bclk_m = 4;
		bclk_n = 90;
		break;

	case 675000:
		bclk_m = 8;
		bclk_n = 225;
		break;
	}

	if (!acomp || !acomp->ops)
		return -ENODEV;

	return acomp->ops->get_cdclk_freq(acomp->dev);
	snd_hdac_chip_writew(bus, HSW_EM4, bclk_m);
	snd_hdac_chip_writew(bus, HSW_EM5, bclk_n);
}
EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk);
EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk);

/* There is a fixed mapping between audio pin node and display port
 * on current Intel platforms:
+4 −52
Original line number Diff line number Diff line
@@ -857,50 +857,6 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
#define azx_del_card_list(chip) /* NOP */
#endif /* CONFIG_PM */

/* Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK
 * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value)
 * are used to convert CDClk (Core Display Clock) to 24MHz BCLK:
 * BCLK = CDCLK * M / N
 * The values will be lost when the display power well is disabled and need to
 * be restored to avoid abnormal playback speed.
 */
static void haswell_set_bclk(struct hda_intel *hda)
{
	struct azx *chip = &hda->chip;
	int cdclk_freq;
	unsigned int bclk_m, bclk_n;

	if (!hda->need_i915_power)
		return;

	cdclk_freq = snd_hdac_get_display_clk(azx_bus(chip));
	switch (cdclk_freq) {
	case 337500:
		bclk_m = 16;
		bclk_n = 225;
		break;

	case 450000:
	default: /* default CDCLK 450MHz */
		bclk_m = 4;
		bclk_n = 75;
		break;

	case 540000:
		bclk_m = 4;
		bclk_n = 90;
		break;

	case 675000:
		bclk_m = 8;
		bclk_n = 225;
		break;
	}

	azx_writew(chip, HSW_EM4, bclk_m);
	azx_writew(chip, HSW_EM5, bclk_n);
}

#if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO)
/*
 * power management
@@ -958,7 +914,7 @@ static int azx_resume(struct device *dev)
	if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
		&& hda->need_i915_power) {
		snd_hdac_display_power(azx_bus(chip), true);
		haswell_set_bclk(hda);
		snd_hdac_i915_set_bclk(azx_bus(chip));
	}
	if (chip->msi)
		if (pci_enable_msi(pci) < 0)
@@ -1058,7 +1014,7 @@ static int azx_runtime_resume(struct device *dev)
		bus = azx_bus(chip);
		if (hda->need_i915_power) {
			snd_hdac_display_power(bus, true);
			haswell_set_bclk(hda);
			snd_hdac_i915_set_bclk(bus);
		} else {
			/* toggle codec wakeup bit for STATESTS read */
			snd_hdac_set_codec_wakeup(bus, true);
@@ -1796,12 +1752,8 @@ static int azx_first_init(struct azx *chip)
	/* initialize chip */
	azx_init_pci(chip);

	if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
		struct hda_intel *hda;

		hda = container_of(chip, struct hda_intel, chip);
		haswell_set_bclk(hda);
	}
	if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
		snd_hdac_i915_set_bclk(bus);

	hda_intel_init_chip(chip, (probe_only[dev] & 2) == 0);

+1 −0
Original line number Diff line number Diff line
@@ -2232,6 +2232,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port)
	if (atomic_read(&(codec)->core.in_pm))
		return;

	snd_hdac_i915_set_bclk(&codec->bus->core);
	check_presence_and_report(codec, pin_nid);
}

Loading