Merge branch 'for-linus' into for-next
For taking back the recent change of HDA HDMI fixes for i915 HSW/BDW. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Коммит
a33d595996
|
@ -9,7 +9,7 @@
|
||||||
#ifdef CONFIG_SND_HDA_I915
|
#ifdef CONFIG_SND_HDA_I915
|
||||||
int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
|
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_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_device *codec, hda_nid_t nid, int rate);
|
int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
|
||||||
int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
|
int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
|
||||||
bool *audio_enabled, char *buffer, int max_bytes);
|
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;
|
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_device *codec,
|
static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
|
||||||
hda_nid_t nid, int rate)
|
hda_nid_t nid, int rate)
|
||||||
|
|
|
@ -17,6 +17,8 @@ int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec,
|
||||||
unsigned int verb);
|
unsigned int verb);
|
||||||
int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
|
int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
|
||||||
unsigned int *val);
|
unsigned int *val);
|
||||||
|
int snd_hdac_regmap_read_raw_uncached(struct hdac_device *codec,
|
||||||
|
unsigned int reg, unsigned int *val);
|
||||||
int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
|
int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
|
||||||
unsigned int val);
|
unsigned int val);
|
||||||
int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
|
int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
|
||||||
|
|
|
@ -299,13 +299,11 @@ EXPORT_SYMBOL_GPL(_snd_hdac_read_parm);
|
||||||
int snd_hdac_read_parm_uncached(struct hdac_device *codec, hda_nid_t nid,
|
int snd_hdac_read_parm_uncached(struct hdac_device *codec, hda_nid_t nid,
|
||||||
int parm)
|
int parm)
|
||||||
{
|
{
|
||||||
int val;
|
unsigned int cmd, val;
|
||||||
|
|
||||||
if (codec->regmap)
|
cmd = snd_hdac_regmap_encode_verb(nid, AC_VERB_PARAMETERS) | parm;
|
||||||
regcache_cache_bypass(codec->regmap, true);
|
if (snd_hdac_regmap_read_raw_uncached(codec, cmd, &val) < 0)
|
||||||
val = snd_hdac_read_parm(codec, nid, parm);
|
return -1;
|
||||||
if (codec->regmap)
|
|
||||||
regcache_cache_bypass(codec->regmap, false);
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_hdac_read_parm_uncached);
|
EXPORT_SYMBOL_GPL(snd_hdac_read_parm_uncached);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/hdaudio.h>
|
#include <sound/hdaudio.h>
|
||||||
#include <sound/hda_i915.h>
|
#include <sound/hda_i915.h>
|
||||||
|
#include <sound/hda_register.h>
|
||||||
|
|
||||||
static struct i915_audio_component *hdac_acomp;
|
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);
|
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
|
* @bus: HDA core bus
|
||||||
*
|
*
|
||||||
* This function is supposed to be used only by a HD-audio controller
|
* Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK
|
||||||
* driver that needs the interaction with i915 graphics.
|
* 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
|
* Call this function at initializing and changing power well, as well as
|
||||||
* returns the value. A negative code is returned in error.
|
* 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 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)
|
if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq)
|
||||||
return -ENODEV;
|
return; /* only for i915 binding */
|
||||||
|
if (!CONTROLLER_IN_GPU(pci))
|
||||||
|
return; /* only HSW/BDW */
|
||||||
|
|
||||||
return acomp->ops->get_cdclk_freq(acomp->dev);
|
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;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk);
|
|
||||||
|
snd_hdac_chip_writew(bus, HSW_EM4, bclk_m);
|
||||||
|
snd_hdac_chip_writew(bus, HSW_EM5, bclk_n);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk);
|
||||||
|
|
||||||
/* There is a fixed mapping between audio pin node and display port.
|
/* There is a fixed mapping between audio pin node and display port.
|
||||||
* on SNB, IVY, HSW, BSW, SKL, BXT, KBL:
|
* on SNB, IVY, HSW, BSW, SKL, BXT, KBL:
|
||||||
|
|
|
@ -453,14 +453,30 @@ int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
|
||||||
EXPORT_SYMBOL_GPL(snd_hdac_regmap_write_raw);
|
EXPORT_SYMBOL_GPL(snd_hdac_regmap_write_raw);
|
||||||
|
|
||||||
static int reg_raw_read(struct hdac_device *codec, unsigned int reg,
|
static int reg_raw_read(struct hdac_device *codec, unsigned int reg,
|
||||||
unsigned int *val)
|
unsigned int *val, bool uncached)
|
||||||
{
|
{
|
||||||
if (!codec->regmap)
|
if (uncached || !codec->regmap)
|
||||||
return hda_reg_read(codec, reg, val);
|
return hda_reg_read(codec, reg, val);
|
||||||
else
|
else
|
||||||
return regmap_read(codec->regmap, reg, val);
|
return regmap_read(codec->regmap, reg, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __snd_hdac_regmap_read_raw(struct hdac_device *codec,
|
||||||
|
unsigned int reg, unsigned int *val,
|
||||||
|
bool uncached)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = reg_raw_read(codec, reg, val, uncached);
|
||||||
|
if (err == -EAGAIN) {
|
||||||
|
err = snd_hdac_power_up_pm(codec);
|
||||||
|
if (!err)
|
||||||
|
err = reg_raw_read(codec, reg, val, uncached);
|
||||||
|
snd_hdac_power_down_pm(codec);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_hdac_regmap_read_raw - read a pseudo register with power mgmt
|
* snd_hdac_regmap_read_raw - read a pseudo register with power mgmt
|
||||||
* @codec: the codec object
|
* @codec: the codec object
|
||||||
|
@ -472,19 +488,19 @@ static int reg_raw_read(struct hdac_device *codec, unsigned int reg,
|
||||||
int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
|
int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
|
||||||
unsigned int *val)
|
unsigned int *val)
|
||||||
{
|
{
|
||||||
int err;
|
return __snd_hdac_regmap_read_raw(codec, reg, val, false);
|
||||||
|
|
||||||
err = reg_raw_read(codec, reg, val);
|
|
||||||
if (err == -EAGAIN) {
|
|
||||||
err = snd_hdac_power_up_pm(codec);
|
|
||||||
if (!err)
|
|
||||||
err = reg_raw_read(codec, reg, val);
|
|
||||||
snd_hdac_power_down_pm(codec);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_hdac_regmap_read_raw);
|
EXPORT_SYMBOL_GPL(snd_hdac_regmap_read_raw);
|
||||||
|
|
||||||
|
/* Works like snd_hdac_regmap_read_raw(), but this doesn't read from the
|
||||||
|
* cache but always via hda verbs.
|
||||||
|
*/
|
||||||
|
int snd_hdac_regmap_read_raw_uncached(struct hdac_device *codec,
|
||||||
|
unsigned int reg, unsigned int *val)
|
||||||
|
{
|
||||||
|
return __snd_hdac_regmap_read_raw(codec, reg, val, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_hdac_regmap_update_raw - update a pseudo register with power mgmt
|
* snd_hdac_regmap_update_raw - update a pseudo register with power mgmt
|
||||||
* @codec: the codec object
|
* @codec: the codec object
|
||||||
|
|
|
@ -591,7 +591,7 @@ static int sscape_upload_microcode(struct snd_card *card, int version)
|
||||||
}
|
}
|
||||||
err = upload_dma_data(sscape, init_fw->data, init_fw->size);
|
err = upload_dma_data(sscape, init_fw->data, init_fw->size);
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
snd_printk(KERN_INFO "sscape: MIDI firmware loaded %d KBs\n",
|
snd_printk(KERN_INFO "sscape: MIDI firmware loaded %zu KBs\n",
|
||||||
init_fw->size >> 10);
|
init_fw->size >> 10);
|
||||||
|
|
||||||
release_firmware(init_fw);
|
release_firmware(init_fw);
|
||||||
|
|
|
@ -826,7 +826,7 @@ static hda_nid_t path_power_update(struct hda_codec *codec,
|
||||||
bool allow_powerdown)
|
bool allow_powerdown)
|
||||||
{
|
{
|
||||||
hda_nid_t nid, changed = 0;
|
hda_nid_t nid, changed = 0;
|
||||||
int i, state;
|
int i, state, power;
|
||||||
|
|
||||||
for (i = 0; i < path->depth; i++) {
|
for (i = 0; i < path->depth; i++) {
|
||||||
nid = path->path[i];
|
nid = path->path[i];
|
||||||
|
@ -838,7 +838,9 @@ static hda_nid_t path_power_update(struct hda_codec *codec,
|
||||||
state = AC_PWRST_D0;
|
state = AC_PWRST_D0;
|
||||||
else
|
else
|
||||||
state = AC_PWRST_D3;
|
state = AC_PWRST_D3;
|
||||||
if (!snd_hda_check_power_state(codec, nid, state)) {
|
power = snd_hda_codec_read(codec, nid, 0,
|
||||||
|
AC_VERB_GET_POWER_STATE, 0);
|
||||||
|
if (power != (state | (state << 4))) {
|
||||||
snd_hda_codec_write(codec, nid, 0,
|
snd_hda_codec_write(codec, nid, 0,
|
||||||
AC_VERB_SET_POWER_STATE, state);
|
AC_VERB_SET_POWER_STATE, state);
|
||||||
changed = nid;
|
changed = nid;
|
||||||
|
|
|
@ -857,50 +857,6 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
|
||||||
#define azx_del_card_list(chip) /* NOP */
|
#define azx_del_card_list(chip) /* NOP */
|
||||||
#endif /* CONFIG_PM */
|
#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)
|
#if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO)
|
||||||
/*
|
/*
|
||||||
* power management
|
* power management
|
||||||
|
@ -958,7 +914,7 @@ static int azx_resume(struct device *dev)
|
||||||
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
|
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
|
||||||
&& hda->need_i915_power) {
|
&& hda->need_i915_power) {
|
||||||
snd_hdac_display_power(azx_bus(chip), true);
|
snd_hdac_display_power(azx_bus(chip), true);
|
||||||
haswell_set_bclk(hda);
|
snd_hdac_i915_set_bclk(azx_bus(chip));
|
||||||
}
|
}
|
||||||
if (chip->msi)
|
if (chip->msi)
|
||||||
if (pci_enable_msi(pci) < 0)
|
if (pci_enable_msi(pci) < 0)
|
||||||
|
@ -1058,7 +1014,7 @@ static int azx_runtime_resume(struct device *dev)
|
||||||
bus = azx_bus(chip);
|
bus = azx_bus(chip);
|
||||||
if (hda->need_i915_power) {
|
if (hda->need_i915_power) {
|
||||||
snd_hdac_display_power(bus, true);
|
snd_hdac_display_power(bus, true);
|
||||||
haswell_set_bclk(hda);
|
snd_hdac_i915_set_bclk(bus);
|
||||||
} else {
|
} else {
|
||||||
/* toggle codec wakeup bit for STATESTS read */
|
/* toggle codec wakeup bit for STATESTS read */
|
||||||
snd_hdac_set_codec_wakeup(bus, true);
|
snd_hdac_set_codec_wakeup(bus, true);
|
||||||
|
@ -1796,12 +1752,8 @@ static int azx_first_init(struct azx *chip)
|
||||||
/* initialize chip */
|
/* initialize chip */
|
||||||
azx_init_pci(chip);
|
azx_init_pci(chip);
|
||||||
|
|
||||||
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
|
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
|
||||||
struct hda_intel *hda;
|
snd_hdac_i915_set_bclk(bus);
|
||||||
|
|
||||||
hda = container_of(chip, struct hda_intel, chip);
|
|
||||||
haswell_set_bclk(hda);
|
|
||||||
}
|
|
||||||
|
|
||||||
hda_intel_init_chip(chip, (probe_only[dev] & 2) == 0);
|
hda_intel_init_chip(chip, (probe_only[dev] & 2) == 0);
|
||||||
|
|
||||||
|
@ -2232,6 +2184,9 @@ static const struct pci_device_id azx_ids[] = {
|
||||||
/* Broxton-P(Apollolake) */
|
/* Broxton-P(Apollolake) */
|
||||||
{ PCI_DEVICE(0x8086, 0x5a98),
|
{ PCI_DEVICE(0x8086, 0x5a98),
|
||||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
|
||||||
|
/* Broxton-T */
|
||||||
|
{ PCI_DEVICE(0x8086, 0x1a98),
|
||||||
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
|
||||||
/* Haswell */
|
/* Haswell */
|
||||||
{ PCI_DEVICE(0x8086, 0x0a0c),
|
{ PCI_DEVICE(0x8086, 0x0a0c),
|
||||||
.driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
|
.driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
|
||||||
|
|
|
@ -361,6 +361,7 @@ static int cs_parse_auto_config(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct cs_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
int err;
|
int err;
|
||||||
|
int i;
|
||||||
|
|
||||||
err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0);
|
err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -370,6 +371,19 @@ static int cs_parse_auto_config(struct hda_codec *codec)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
/* keep the ADCs powered up when it's dynamically switchable */
|
||||||
|
if (spec->gen.dyn_adc_switch) {
|
||||||
|
unsigned int done = 0;
|
||||||
|
for (i = 0; i < spec->gen.input_mux.num_items; i++) {
|
||||||
|
int idx = spec->gen.dyn_adc_idx[i];
|
||||||
|
if (done & (1 << idx))
|
||||||
|
continue;
|
||||||
|
snd_hda_gen_fix_pin_power(codec,
|
||||||
|
spec->gen.adc_nids[idx]);
|
||||||
|
done |= 1 << idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1397,7 +1397,6 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
|
||||||
struct hda_codec *codec = per_pin->codec;
|
struct hda_codec *codec = per_pin->codec;
|
||||||
struct hdmi_spec *spec = codec->spec;
|
struct hdmi_spec *spec = codec->spec;
|
||||||
struct hdmi_eld *eld = &spec->temp_eld;
|
struct hdmi_eld *eld = &spec->temp_eld;
|
||||||
struct hdmi_eld *pin_eld = &per_pin->sink_eld;
|
|
||||||
hda_nid_t pin_nid = per_pin->pin_nid;
|
hda_nid_t pin_nid = per_pin->pin_nid;
|
||||||
/*
|
/*
|
||||||
* Always execute a GetPinSense verb here, even when called from
|
* Always execute a GetPinSense verb here, even when called from
|
||||||
|
@ -1414,15 +1413,15 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
|
||||||
present = snd_hda_pin_sense(codec, pin_nid);
|
present = snd_hda_pin_sense(codec, pin_nid);
|
||||||
|
|
||||||
mutex_lock(&per_pin->lock);
|
mutex_lock(&per_pin->lock);
|
||||||
pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
|
eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
|
||||||
if (pin_eld->monitor_present)
|
if (eld->monitor_present)
|
||||||
eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
|
eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
|
||||||
else
|
else
|
||||||
eld->eld_valid = false;
|
eld->eld_valid = false;
|
||||||
|
|
||||||
codec_dbg(codec,
|
codec_dbg(codec,
|
||||||
"HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
|
"HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
|
||||||
codec->addr, pin_nid, pin_eld->monitor_present, eld->eld_valid);
|
codec->addr, pin_nid, eld->monitor_present, eld->eld_valid);
|
||||||
|
|
||||||
if (eld->eld_valid) {
|
if (eld->eld_valid) {
|
||||||
if (spec->ops.pin_get_eld(codec, pin_nid, eld->eld_buffer,
|
if (spec->ops.pin_get_eld(codec, pin_nid, eld->eld_buffer,
|
||||||
|
@ -1442,7 +1441,7 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
|
||||||
else
|
else
|
||||||
update_eld(codec, per_pin, eld);
|
update_eld(codec, per_pin, eld);
|
||||||
|
|
||||||
ret = !repoll || !pin_eld->monitor_present || pin_eld->eld_valid;
|
ret = !repoll || !eld->monitor_present || eld->eld_valid;
|
||||||
|
|
||||||
jack = snd_hda_jack_tbl_get(codec, pin_nid);
|
jack = snd_hda_jack_tbl_get(codec, pin_nid);
|
||||||
if (jack)
|
if (jack)
|
||||||
|
@ -1870,6 +1869,8 @@ static void hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
|
||||||
struct hdmi_spec *spec = codec->spec;
|
struct hdmi_spec *spec = codec->spec;
|
||||||
struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
|
struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
|
||||||
|
|
||||||
|
if (!per_pin)
|
||||||
|
return;
|
||||||
mutex_lock(&per_pin->lock);
|
mutex_lock(&per_pin->lock);
|
||||||
per_pin->chmap_set = true;
|
per_pin->chmap_set = true;
|
||||||
memcpy(per_pin->chmap, chmap, ARRAY_SIZE(per_pin->chmap));
|
memcpy(per_pin->chmap, chmap, ARRAY_SIZE(per_pin->chmap));
|
||||||
|
@ -2313,6 +2314,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port)
|
||||||
if (atomic_read(&(codec)->core.in_pm))
|
if (atomic_read(&(codec)->core.in_pm))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
snd_hdac_i915_set_bclk(&codec->bus->core);
|
||||||
check_presence_and_report(codec, pin_nid);
|
check_presence_and_report(codec, pin_nid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4760,6 +4760,7 @@ enum {
|
||||||
ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
|
ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
|
||||||
ALC280_FIXUP_HP_HEADSET_MIC,
|
ALC280_FIXUP_HP_HEADSET_MIC,
|
||||||
ALC221_FIXUP_HP_FRONT_MIC,
|
ALC221_FIXUP_HP_FRONT_MIC,
|
||||||
|
ALC292_FIXUP_TPT460,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct hda_fixup alc269_fixups[] = {
|
static const struct hda_fixup alc269_fixups[] = {
|
||||||
|
@ -5409,6 +5410,12 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||||
{ }
|
{ }
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
[ALC292_FIXUP_TPT460] = {
|
||||||
|
.type = HDA_FIXUP_FUNC,
|
||||||
|
.v.func = alc_fixup_tpt440_dock,
|
||||||
|
.chained = true,
|
||||||
|
.chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
|
@ -5442,6 +5449,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
|
SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
|
||||||
|
SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
|
SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
|
||||||
SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||||
|
@ -5563,7 +5571,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
|
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, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
|
SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
|
SND_PCI_QUIRK(0x17aa, 0x30e2, "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, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
|
||||||
|
@ -5576,6 +5584,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
|
||||||
|
SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
|
SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
|
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
|
||||||
|
@ -5658,6 +5667,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
|
||||||
{.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
|
{.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
|
||||||
{.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
|
{.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
|
||||||
{.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
|
{.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
|
||||||
|
{.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
#define ALC225_STANDARD_PINS \
|
#define ALC225_STANDARD_PINS \
|
||||||
|
|
|
@ -1341,5 +1341,6 @@ irqreturn_t pcxhr_threaded_irq(int irq, void *dev_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pcxhr_msg_thread(mgr);
|
pcxhr_msg_thread(mgr);
|
||||||
|
mutex_unlock(&mgr->lock);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,6 +348,16 @@ static struct usbmix_name_map bose_companion5_map[] = {
|
||||||
{ 0 } /* terminator */
|
{ 0 } /* terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dell usb dock with ALC4020 codec had a firmware problem where it got
|
||||||
|
* screwed up when zero volume is passed; just skip it as a workaround
|
||||||
|
*/
|
||||||
|
static const struct usbmix_name_map dell_alc4020_map[] = {
|
||||||
|
{ 16, NULL },
|
||||||
|
{ 19, NULL },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Control map entries
|
* Control map entries
|
||||||
*/
|
*/
|
||||||
|
@ -430,6 +440,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
|
||||||
.id = USB_ID(0x0ccd, 0x0028),
|
.id = USB_ID(0x0ccd, 0x0028),
|
||||||
.map = aureon_51_2_map,
|
.map = aureon_51_2_map,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.id = USB_ID(0x0bda, 0x4014),
|
||||||
|
.map = dell_alc4020_map,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.id = USB_ID(0x0dba, 0x1000),
|
.id = USB_ID(0x0dba, 0x1000),
|
||||||
.map = mbox1_map,
|
.map = mbox1_map,
|
||||||
|
|
|
@ -1134,6 +1134,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
|
||||||
case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */
|
case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */
|
||||||
case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */
|
case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */
|
||||||
case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */
|
case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */
|
||||||
|
case USB_ID(0x047F, 0x0415): /* Plantronics BT-300 */
|
||||||
case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */
|
case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */
|
||||||
case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
|
case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
|
||||||
case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
|
case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче