[alsa-devel] [PATCH 1/3] ALSA: hda - Clearing jackpoll_interval avoid pending work
Clearing jackpoll_interval before calling cancel_delayed_work_sync(), otherwise the work will be triggered again and cause impact in hda_jackpoll_work(). The next patch will poll jack once even with jackpoll_interval=0.
Signed-off-by: Wang Xingchao xingchao.wang@linux.intel.com --- sound/pci/hda/patch_via.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index e2481ba..0bc20ef 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -207,9 +207,9 @@ static void vt1708_stop_hp_work(struct hda_codec *codec) return; if (spec->hp_work_active) { snd_hda_codec_write(codec, 0x1, 0, 0xf81, 1); + codec->jackpoll_interval = 0; cancel_delayed_work_sync(&codec->jackpoll_work); spec->hp_work_active = false; - codec->jackpoll_interval = 0; } }
With jackpoll_interval != 0, it's used to poll jack event periodically in a delayed work. if it's 0, give the caller chance to probe jack status but will not restart the delayed work.
In the next patch which enable WAKEEN feature, HDA controller was able to wake up system when it's in D3, it's useful to detect Jack hotplug event and notify userspace. By default the jackpoll_interval=0, this patch let jack poll once without starting the delayed work.
Signed-off-by: Wang Xingchao xingchao.wang@linux.intel.com --- sound/pci/hda/hda_codec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 8a005f0..fdbb09a 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1216,11 +1216,13 @@ static void hda_jackpoll_work(struct work_struct *work) { struct hda_codec *codec = container_of(work, struct hda_codec, jackpoll_work.work); - if (!codec->jackpoll_interval) - return;
snd_hda_jack_set_dirty_all(codec); snd_hda_jack_poll_all(codec); + + if (!codec->jackpoll_interval) + return; + queue_delayed_work(codec->bus->workq, &codec->jackpoll_work, codec->jackpoll_interval); }
With runtime power save feature enabled, Headphone hotplug event will not be detected while controller/codec in D3. HDA has feature WAKEEN to let codec wake up system if controller is in D3 or system in S3.(HDA Spec 4.5.9.2/3). Codec can send out INT or wake up controller depending on whether CIE or GIE enabled.(Figure 4, Interupt structure).
The controller must be in RESET mode after enter runtime-suspend, otherwise it will not be waken up even if codec send out wake-up event. And STATESTS will be cleared after controller brought out of RESET mode.
This patch only enable WAKEEN for runtime-suspend(Controller D3) mode, not for system S3 mode. with tool "evtest", Headphone hotplug events could be cought and reported successfully.
Signed-off-by: Wang Xingchao xingchao.wang@linux.intel.com --- sound/pci/hda/hda_intel.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 8860dd5..c848cf1 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2971,6 +2971,10 @@ static int azx_runtime_suspend(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data;
+ /* enable controller wake up event */ + azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) | + STATESTS_INT_MASK); + azx_stop_chip(chip); azx_enter_link_reset(chip); azx_clear_irq_pending(chip); @@ -2983,11 +2987,31 @@ static int azx_runtime_resume(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; + struct hda_bus *bus; + struct hda_codec *codec; + int status;
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) hda_display_power(true); + + /* Read STATESTS before controller reset */ + status = azx_readw(chip, STATESTS); + azx_init_pci(chip); azx_init_chip(chip, 1); + + bus = chip->bus; + if (status && bus) { + list_for_each_entry(codec, &bus->codec_list, list) + if (status & (1 << codec->addr)) + queue_delayed_work(codec->bus->workq, + &codec->jackpoll_work, codec->jackpoll_interval); + } + + /* disable controller Wake Up event*/ + azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & + ~STATESTS_INT_MASK); + return 0; }
participants (1)
-
Wang Xingchao