Commit 213ed4b8 authored by Takashi Iwai's avatar Takashi Iwai

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: default avatarTakashi Iwai <tiwai@suse.de>
parents 98e3e43b 64ca9d9f
...@@ -358,6 +358,9 @@ struct hdac_bus { ...@@ -358,6 +358,9 @@ struct hdac_bus {
bool align_bdle_4k:1; /* BDLE align 4K boundary */ bool align_bdle_4k:1; /* BDLE align 4K boundary */
bool reverse_assign:1; /* assign devices in reverse order */ bool reverse_assign:1; /* assign devices in reverse order */
bool corbrp_self_clear:1; /* CORBRP clears itself after reset */ bool corbrp_self_clear:1; /* CORBRP clears itself after reset */
bool polling_mode:1;
int poll_count;
int bdl_pos_adj; /* BDL position adjustment */ int bdl_pos_adj; /* BDL position adjustment */
......
...@@ -239,6 +239,8 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, ...@@ -239,6 +239,8 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
timeout = jiffies + msecs_to_jiffies(1000); timeout = jiffies + msecs_to_jiffies(1000);
for (loopcounter = 0;; loopcounter++) { for (loopcounter = 0;; loopcounter++) {
if (bus->polling_mode)
snd_hdac_bus_update_rirb(bus);
spin_lock_irq(&bus->reg_lock); spin_lock_irq(&bus->reg_lock);
if (!bus->rirb.cmds[addr]) { if (!bus->rirb.cmds[addr]) {
if (res) if (res)
......
...@@ -806,11 +806,11 @@ static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr, ...@@ -806,11 +806,11 @@ static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr,
for (loopcounter = 0;; loopcounter++) { for (loopcounter = 0;; loopcounter++) {
spin_lock_irq(&bus->reg_lock); spin_lock_irq(&bus->reg_lock);
if (chip->polling_mode || do_poll) if (bus->polling_mode || do_poll)
snd_hdac_bus_update_rirb(bus); snd_hdac_bus_update_rirb(bus);
if (!bus->rirb.cmds[addr]) { if (!bus->rirb.cmds[addr]) {
if (!do_poll) if (!do_poll)
chip->poll_count = 0; bus->poll_count = 0;
if (res) if (res)
*res = bus->rirb.res[addr]; /* the last value */ *res = bus->rirb.res[addr]; /* the last value */
spin_unlock_irq(&bus->reg_lock); spin_unlock_irq(&bus->reg_lock);
...@@ -830,21 +830,21 @@ static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr, ...@@ -830,21 +830,21 @@ static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr,
if (hbus->no_response_fallback) if (hbus->no_response_fallback)
return -EIO; return -EIO;
if (!chip->polling_mode && chip->poll_count < 2) { if (!bus->polling_mode && bus->poll_count < 2) {
dev_dbg(chip->card->dev, dev_dbg(chip->card->dev,
"azx_get_response timeout, polling the codec once: last cmd=0x%08x\n", "azx_get_response timeout, polling the codec once: last cmd=0x%08x\n",
bus->last_cmd[addr]); bus->last_cmd[addr]);
do_poll = 1; do_poll = 1;
chip->poll_count++; bus->poll_count++;
goto again; goto again;
} }
if (!chip->polling_mode) { if (!bus->polling_mode) {
dev_warn(chip->card->dev, dev_warn(chip->card->dev,
"azx_get_response timeout, switching to polling mode: last cmd=0x%08x\n", "azx_get_response timeout, switching to polling mode: last cmd=0x%08x\n",
bus->last_cmd[addr]); bus->last_cmd[addr]);
chip->polling_mode = 1; bus->polling_mode = 1;
goto again; goto again;
} }
......
...@@ -142,11 +142,9 @@ struct azx { ...@@ -142,11 +142,9 @@ struct azx {
/* flags */ /* flags */
int bdl_pos_adj; int bdl_pos_adj;
int poll_count;
unsigned int running:1; unsigned int running:1;
unsigned int fallback_to_single_cmd:1; unsigned int fallback_to_single_cmd:1;
unsigned int single_cmd:1; unsigned int single_cmd:1;
unsigned int polling_mode:1;
unsigned int msi:1; unsigned int msi:1;
unsigned int probing:1; /* codec probing phase */ unsigned int probing:1; /* codec probing phase */
unsigned int snoop:1; unsigned int snoop:1;
......
...@@ -375,6 +375,7 @@ enum { ...@@ -375,6 +375,7 @@ enum {
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348) #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[] = { static char *driver_short_names[] = {
[AZX_DRIVER_ICH] = "HDA Intel", [AZX_DRIVER_ICH] = "HDA Intel",
...@@ -1700,10 +1701,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, ...@@ -1700,10 +1701,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
else else
chip->bdl_pos_adj = bdl_pos_adj[dev]; 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); err = azx_bus_init(chip, model[dev], &pci_hda_io_ops);
if (err < 0) { if (err < 0) {
kfree(hda); kfree(hda);
...@@ -1711,6 +1708,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, ...@@ -1711,6 +1708,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
return err; 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) { if (chip->driver_type == AZX_DRIVER_NVIDIA) {
dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n"); dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n");
chip->bus.needs_damn_long_delay = 1; chip->bus.needs_damn_long_delay = 1;
......
...@@ -834,6 +834,8 @@ static void alc_pre_init(struct hda_codec *codec) ...@@ -834,6 +834,8 @@ static void alc_pre_init(struct hda_codec *codec)
alc_fill_eapd_coef(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) \ #define is_s4_resume(codec) \
((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE) ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
...@@ -4901,6 +4903,8 @@ static void alc_update_headset_mode(struct hda_codec *codec) ...@@ -4901,6 +4903,8 @@ static void alc_update_headset_mode(struct hda_codec *codec)
switch (new_headset_mode) { switch (new_headset_mode) {
case ALC_HEADSET_MODE_UNPLUGGED: case ALC_HEADSET_MODE_UNPLUGGED:
alc_headset_mode_unplugged(codec); 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; spec->gen.hp_jack_present = false;
break; break;
case ALC_HEADSET_MODE_HEADSET: case ALC_HEADSET_MODE_HEADSET:
...@@ -4943,8 +4947,6 @@ static void alc_update_headset_mode_hook(struct hda_codec *codec, ...@@ -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, static void alc_update_headset_jack_cb(struct hda_codec *codec,
struct hda_jack_callback *jack) 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); snd_hda_gen_hp_automute(codec, jack);
} }
...@@ -4981,7 +4983,10 @@ static void alc_fixup_headset_mode(struct hda_codec *codec, ...@@ -4981,7 +4983,10 @@ static void alc_fixup_headset_mode(struct hda_codec *codec,
alc_probe_headset_mode(codec); alc_probe_headset_mode(codec);
break; break;
case HDA_FIXUP_ACT_INIT: 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); alc_update_headset_mode(codec);
break; break;
} }
...@@ -5747,7 +5752,7 @@ enum { ...@@ -5747,7 +5752,7 @@ enum {
ALC298_FIXUP_TPT470_DOCK, ALC298_FIXUP_TPT470_DOCK,
ALC255_FIXUP_DUMMY_LINEOUT_VERB, ALC255_FIXUP_DUMMY_LINEOUT_VERB,
ALC255_FIXUP_DELL_HEADSET_MIC, ALC255_FIXUP_DELL_HEADSET_MIC,
ALC256_FIXUP_HUAWEI_MBXP_PINS, ALC256_FIXUP_HUAWEI_MACH_WX9_PINS,
ALC295_FIXUP_HP_X360, ALC295_FIXUP_HP_X360,
ALC221_FIXUP_HP_HEADSET_MIC, ALC221_FIXUP_HP_HEADSET_MIC,
ALC285_FIXUP_LENOVO_HEADPHONE_NOISE, ALC285_FIXUP_LENOVO_HEADPHONE_NOISE,
...@@ -6038,7 +6043,7 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -6038,7 +6043,7 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true, .chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MIC .chain_id = ALC269_FIXUP_HEADSET_MIC
}, },
[ALC256_FIXUP_HUAWEI_MBXP_PINS] = { [ALC256_FIXUP_HUAWEI_MACH_WX9_PINS] = {
.type = HDA_FIXUP_PINS, .type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) { .v.pins = (const struct hda_pintbl[]) {
{0x12, 0x90a60130}, {0x12, 0x90a60130},
...@@ -7063,9 +7068,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -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, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), 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(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
SND_PCI_QUIRK(0x19e5, 0x3200, "Huawei MBX", ALC255_FIXUP_MIC_MUTE_LED), SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
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(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
#if 0 #if 0
...@@ -7124,6 +7127,7 @@ static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = { ...@@ -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(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 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(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) ...@@ -7706,7 +7710,7 @@ static int patch_alc269(struct hda_codec *codec)
spec = codec->spec; spec = codec->spec;
spec->gen.shared_mic_vref_pin = 0x18; spec->gen.shared_mic_vref_pin = 0x18;
codec->power_save_node = 1; codec->power_save_node = 0;
#ifdef CONFIG_PM #ifdef CONFIG_PM
codec->patch_ops.suspend = alc269_suspend; codec->patch_ops.suspend = alc269_suspend;
......
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
/* platform specific devices */ /* platform specific devices */
#include "shim.h" #include "shim.h"
#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348)
#define IS_CNL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9dc8)
/* /*
* Debug * Debug
*/ */
...@@ -213,6 +216,11 @@ static int hda_init(struct snd_sof_dev *sdev) ...@@ -213,6 +216,11 @@ static int hda_init(struct snd_sof_dev *sdev)
ext_ops = snd_soc_hdac_hda_get_ops(); ext_ops = snd_soc_hdac_hda_get_ops();
#endif #endif
sof_hda_bus_init(bus, &pci->dev, ext_ops); 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->use_posbuf = 1;
bus->bdl_pos_adj = 0; bus->bdl_pos_adj = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment