mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-04 12:13:43 +00:00
sound fixes for 4.6-rc5
Again a relatively calm week without surprise: most of fixes are about HD-audio, including fixes for Cirrus codec regression and a race over regmap access. Although both change are slightly unintuitive, the risk of further breakage is quite low, I hope. Other than that, all the rest are trivial. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJXGeZhAAoJEGwxgFQ9KSmkOg4P/RWGLla59n6L6QCE2kNp3rQS fPjVG2ctEHAqVi6lqLSletV2HkA1K6MY/tyawjtjG2Fs6JqbITasOWJmI10aDzDl tmLWBlmJf4zRye2YbFmP4v5dE9VuRhU9ucMc4IqBT9+DgTEVNuCcQiW9amyj4kJ7 XcjT6z0tj/5MXe+hmjvHuEwc6qYk/4Z7HJDcKlNxsD7dQ9zoLhXmbEndw5600Os5 cMFzZzRPDofyRbvhooQrn1oJG143bilnseMV83O7WTwzJ+DSiZlJG8ibY7bPYsPL qicr4keet5n96gZHbPXeZHvxlCzW4dStna1qPYOWTg8xy1kHGA7tAExznPG23f2h ANTQ0lAN+A0I3PjB0S+MP6I2Uw+bkkKpo0w6ugSz8nmSfO1k9mkavK51RWAuQTef ITdORv/HTkCHp7jyKBx2ArM+s3mckrNA4kNFOAHYpdXln3vQDPc0BnQkfq1LW6vf RQVQSAoSBqZahefgfL2nuhHWa/QqZ+9XTPmxp1dA2YLmYLKtkGOZYuz0XkDYqSaC JdnL+3Q7OmTbVvgPPOn595eq7R8VrH2vbQH1pJC+zRL+I9dVmZ7Et7KtBYCr0pON G4S+ZieILnMTYdYsEK4jQkC0ZiWwpr+y2Lurz97qVm8yIbKSBEpxakxpVHNP5dDe I/6ZrY3i3K4YqYbxPwEF =wz0C -----END PGP SIGNATURE----- Merge tag 'sound-4.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "Again a relatively calm week without surprise: most of fixes are about HD-audio, including fixes for Cirrus codec regression and a race over regmap access. Although both change are slightly unintuitive, the risk of further breakage is quite low, I hope. Other than that, all the rest are trivial" * tag 'sound-4.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda - Fix possible race on regmap bypass flip ALSA: pcxhr: Fix missing mutex unlock ALSA: hda - add PCI ID for Intel Broxton-T ALSA: hda - Keep powering up ADCs on Cirrus codecs ALSA: hda/realtek - Add ALC3234 headset mode for Optiplex 9020m ALSA - hda: hdmi check NULL pointer in hdmi_set_chmap ALSA: hda - Don't trust the reported actual power state
This commit is contained in:
commit
d4b0528827
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -2232,6 +2232,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1858,6 +1858,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));
|
||||||
|
@ -5449,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),
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user