Merge branch 'topic/hda-polling-mode' into for-next

Pull the HD-audio polling mode changes, moving the stuff into HD-audio
core for re-using it in ASoC.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2019-05-28 07:53:38 +02:00
commit 213ed4b807
7 changed files with 37 additions and 21 deletions

View file

@ -358,6 +358,9 @@ struct hdac_bus {
bool align_bdle_4k:1; /* BDLE align 4K boundary */
bool reverse_assign:1; /* assign devices in reverse order */
bool corbrp_self_clear:1; /* CORBRP clears itself after reset */
bool polling_mode:1;
int poll_count;
int bdl_pos_adj; /* BDL position adjustment */

View file

@ -239,6 +239,8 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
timeout = jiffies + msecs_to_jiffies(1000);
for (loopcounter = 0;; loopcounter++) {
if (bus->polling_mode)
snd_hdac_bus_update_rirb(bus);
spin_lock_irq(&bus->reg_lock);
if (!bus->rirb.cmds[addr]) {
if (res)

View file

@ -806,11 +806,11 @@ static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr,
for (loopcounter = 0;; loopcounter++) {
spin_lock_irq(&bus->reg_lock);
if (chip->polling_mode || do_poll)
if (bus->polling_mode || do_poll)
snd_hdac_bus_update_rirb(bus);
if (!bus->rirb.cmds[addr]) {
if (!do_poll)
chip->poll_count = 0;
bus->poll_count = 0;
if (res)
*res = bus->rirb.res[addr]; /* the last value */
spin_unlock_irq(&bus->reg_lock);
@ -830,21 +830,21 @@ static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr,
if (hbus->no_response_fallback)
return -EIO;
if (!chip->polling_mode && chip->poll_count < 2) {
if (!bus->polling_mode && bus->poll_count < 2) {
dev_dbg(chip->card->dev,
"azx_get_response timeout, polling the codec once: last cmd=0x%08x\n",
bus->last_cmd[addr]);
do_poll = 1;
chip->poll_count++;
bus->poll_count++;
goto again;
}
if (!chip->polling_mode) {
if (!bus->polling_mode) {
dev_warn(chip->card->dev,
"azx_get_response timeout, switching to polling mode: last cmd=0x%08x\n",
bus->last_cmd[addr]);
chip->polling_mode = 1;
bus->polling_mode = 1;
goto again;
}

View file

@ -142,11 +142,9 @@ struct azx {
/* flags */
int bdl_pos_adj;
int poll_count;
unsigned int running:1;
unsigned int fallback_to_single_cmd:1;
unsigned int single_cmd:1;
unsigned int polling_mode:1;
unsigned int msi:1;
unsigned int probing:1; /* codec probing phase */
unsigned int snoop:1;

View file

@ -375,6 +375,7 @@ enum {
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348)
#define IS_CNL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9dc8)
static char *driver_short_names[] = {
[AZX_DRIVER_ICH] = "HDA Intel",
@ -1700,10 +1701,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
else
chip->bdl_pos_adj = bdl_pos_adj[dev];
/* Workaround for a communication error on CFL (bko#199007) */
if (IS_CFL(pci))
chip->polling_mode = 1;
err = azx_bus_init(chip, model[dev], &pci_hda_io_ops);
if (err < 0) {
kfree(hda);
@ -1711,6 +1708,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
return err;
}
/* Workaround for a communication error on CFL (bko#199007) and CNL */
if (IS_CFL(pci) || IS_CNL(pci))
azx_bus(chip)->polling_mode = 1;
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;

View file

@ -834,6 +834,8 @@ static void alc_pre_init(struct hda_codec *codec)
alc_fill_eapd_coef(codec);
}
#define is_s3_resume(codec) \
((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
#define is_s4_resume(codec) \
((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
@ -4901,6 +4903,8 @@ static void alc_update_headset_mode(struct hda_codec *codec)
switch (new_headset_mode) {
case ALC_HEADSET_MODE_UNPLUGGED:
alc_headset_mode_unplugged(codec);
spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
spec->gen.hp_jack_present = false;
break;
case ALC_HEADSET_MODE_HEADSET:
@ -4943,8 +4947,6 @@ static void alc_update_headset_mode_hook(struct hda_codec *codec,
static void alc_update_headset_jack_cb(struct hda_codec *codec,
struct hda_jack_callback *jack)
{
struct alc_spec *spec = codec->spec;
spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
snd_hda_gen_hp_automute(codec, jack);
}
@ -4981,7 +4983,10 @@ static void alc_fixup_headset_mode(struct hda_codec *codec,
alc_probe_headset_mode(codec);
break;
case HDA_FIXUP_ACT_INIT:
spec->current_headset_mode = 0;
if (is_s3_resume(codec) || is_s4_resume(codec)) {
spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
}
alc_update_headset_mode(codec);
break;
}
@ -5747,7 +5752,7 @@ enum {
ALC298_FIXUP_TPT470_DOCK,
ALC255_FIXUP_DUMMY_LINEOUT_VERB,
ALC255_FIXUP_DELL_HEADSET_MIC,
ALC256_FIXUP_HUAWEI_MBXP_PINS,
ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
ALC295_FIXUP_HP_X360,
ALC221_FIXUP_HP_HEADSET_MIC,
ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
@ -6038,7 +6043,7 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MIC
},
[ALC256_FIXUP_HUAWEI_MBXP_PINS] = {
[ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{0x12, 0x90a60130},
@ -7063,9 +7068,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
SND_PCI_QUIRK(0x19e5, 0x3200, "Huawei MBX", ALC255_FIXUP_MIC_MUTE_LED),
SND_PCI_QUIRK(0x19e5, 0x3201, "Huawei MBX", ALC255_FIXUP_MIC_MUTE_LED),
SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MBXP", ALC256_FIXUP_HUAWEI_MBXP_PINS),
SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
#if 0
@ -7124,6 +7127,7 @@ static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
{}
};
@ -7706,7 +7710,7 @@ static int patch_alc269(struct hda_codec *codec)
spec = codec->spec;
spec->gen.shared_mic_vref_pin = 0x18;
codec->power_save_node = 1;
codec->power_save_node = 0;
#ifdef CONFIG_PM
codec->patch_ops.suspend = alc269_suspend;

View file

@ -32,6 +32,9 @@
/* platform specific devices */
#include "shim.h"
#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348)
#define IS_CNL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9dc8)
/*
* Debug
*/
@ -213,6 +216,11 @@ static int hda_init(struct snd_sof_dev *sdev)
ext_ops = snd_soc_hdac_hda_get_ops();
#endif
sof_hda_bus_init(bus, &pci->dev, ext_ops);
/* Workaround for a communication error on CFL (bko#199007) and CNL */
if (IS_CFL(pci) || IS_CNL(pci))
bus->polling_mode = 1;
bus->use_posbuf = 1;
bus->bdl_pos_adj = 0;