Skip to content

Commit

Permalink
ASoC: SOF: Intel: optimise jack detection
Browse files Browse the repository at this point in the history
1. The additional HDA codec mask isn't needed, just check the codec
   jack table.
2. Remove the "status" parameter.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
  • Loading branch information
lyakh authored and ranj063 committed Jul 8, 2019
1 parent 291b5ca commit 1da8b5f
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 44 deletions.
53 changes: 27 additions & 26 deletions sound/soc/sof/intel/hda-codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,53 +38,55 @@ static void hda_codec_load_module(struct hda_codec *codec)
static void hda_codec_load_module(struct hda_codec *codec) {}
#endif

/* check jack status after resuming from suspend mode */
void hda_codec_jack_check(struct snd_sof_dev *sdev, int status)
/* enable controller wake up event for all codecs with jack connectors */
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct hda_bus *hbus = sof_to_hbus(sdev);
struct hdac_bus *bus = sof_to_bus(sdev);
struct hda_codec *codec;
int mask;

/*
* there are two reasons for runtime resume
* (1) waken up by interrupt triggered by WAKEEN feature
* (2) waken up by pm get functions for some audio operations
* For case (1), the bits in status mean which codec triggers
* the interrupt and jacks will be checked on these codecs.
* For case (2), we need to check all the non-hdmi codecs for some
* cases like playback with HDMI or capture with DMIC. In these
* cases, only controller is active and codecs are suspended, so
* codecs can't send unsolicited event to controller. The jack polling
* operation will activate codecs and unsolicited event can work
* even codecs become suspended later.
*/
mask = status ? status : hda->hda_codec_mask;
unsigned int mask = 0;

list_for_each_codec(codec, hbus)
if (mask & BIT(codec->core.addr))
schedule_delayed_work(&codec->jackpoll_work,
codec->jackpoll_interval);
if (codec->jacktbl.used)
mask |= BIT(codec->core.addr);

snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask);
}

/* check jack status after resuming from suspend mode */
void hda_codec_jack_check(struct snd_sof_dev *sdev)
{
struct hda_bus *hbus = sof_to_hbus(sdev);
struct hdac_bus *bus = sof_to_bus(sdev);
struct hda_codec *codec;

/* disable controller Wake Up event*/
snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);

list_for_each_codec(codec, hbus)
/*
* Wake up all jack-detecting codecs regardless whether an event
* has been recorded in STATESTS
*/
if (codec->jacktbl.used)
schedule_delayed_work(&codec->jackpoll_work,
codec->jackpoll_interval);
}
#else
void hda_codec_jack_check(struct snd_sof_dev *sdev, int status) {}
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev) {}
void hda_codec_jack_check(struct snd_sof_dev *sdev) {}
#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */
EXPORT_SYMBOL(hda_codec_jack_wake_enable);
EXPORT_SYMBOL(hda_codec_jack_check);

/* probe individual codec */
static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
{
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct hdac_hda_priv *hda_priv;
#endif
struct hda_bus *hbus = sof_to_hbus(sdev);
struct hdac_device *hdev;

u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) |
(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
u32 resp = -1;
Expand Down Expand Up @@ -114,7 +116,6 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
/* use legacy bus only for HDA codecs, idisp uses ext bus */
if ((resp & 0xFFFF0000) != IDISP_VID_INTEL) {
hdev->type = HDA_DEV_LEGACY;
hda->hda_codec_mask |= BIT(address);
hda_codec_load_module(&hda_priv->codec);
}

Expand Down
18 changes: 4 additions & 14 deletions sound/soc/sof/intel/hda-dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,10 +295,8 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
hda_dsp_ipc_int_disable(sdev);

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
if (IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) && runtime_suspend)
/* enable controller wake up event */
snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK,
hda->hda_codec_mask);
if (runtime_suspend)
hda_codec_jack_wake_enable(sdev);

/* power down all hda link */
snd_hdac_ext_bus_link_power_down_all(bus);
Expand Down Expand Up @@ -339,7 +337,6 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
struct hdac_bus *bus = sof_to_bus(sdev);
struct hdac_ext_link *hlink = NULL;
int status;
#endif
int ret;

Expand All @@ -349,13 +346,6 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
*/
snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0);

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
if (runtime_resume) {
/* read STATESTS before controller reset */
status = snd_hdac_chip_readw(bus, STATESTS);
}
#endif

/* reset and start hda controller */
ret = hda_dsp_ctrl_init_chip(sdev, true);
if (ret < 0) {
Expand All @@ -365,9 +355,9 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
}

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* check jack status based on controller status */
/* check jack status */
if (runtime_resume)
hda_codec_jack_check(sdev, status);
hda_codec_jack_check(sdev);

/* turn off the links that were off before suspend */
list_for_each_entry(hlink, &bus->hlink_list, list) {
Expand Down
6 changes: 2 additions & 4 deletions sound/soc/sof/intel/hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,6 @@ struct sof_intel_hda_dev {

/* DMIC device */
struct platform_device *dmic_dev;

/* hda codec mask excluding hdmi */
u32 hda_codec_mask;
};

static inline struct hdac_bus *sof_to_bus(struct snd_sof_dev *s)
Expand Down Expand Up @@ -558,7 +555,8 @@ void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev,
* HDA Codec operations.
*/
int hda_codec_probe_bus(struct snd_sof_dev *sdev);
void hda_codec_jack_check(struct snd_sof_dev *sdev, int status);
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev);
void hda_codec_jack_check(struct snd_sof_dev *sdev);

#endif /* CONFIG_SND_SOC_SOF_HDA */

Expand Down

0 comments on commit 1da8b5f

Please sign in to comment.