[alsa-devel] RT5640 jack detection
Hi, I'm working with the ALC5640-VB audio codec based on the Realtek RT5640. On my setup the codec is only used for audio output through an headphone jack, otherwise the audio should be routed via HDMI.
The problem is that the jack sensing only works when the codec is actively playing something, that is when the bias set for the codec is not SND_SOC_BIAS_OFF. When the codec is suspended and it is powered off I'm not able to detect anymore the presence of the jack. Because of this issue actively switching the audio from HDMI to HP when the jack is inserted is not working.
The driver I'm using for the RT5640 in the .set_bias_level hook function among other things is gating the I2S input clock and this seems to prevent the generation of the IRQ signal I'm using to detect the presence/absence of the jack (the culprit here is MX-FA[0] bit for those interested).
I can easily modify the codec driver to avoid gating the I2S clock when the bias is off but this seems in contrast with the whole DAPM principle.
How this is usually supposed to be working?
+ Realtek
On Tue, 2015-09-22 at 11:18 +0200, Carlo Caione wrote:
Hi, I'm working with the ALC5640-VB audio codec based on the Realtek RT5640. On my setup the codec is only used for audio output through an headphone jack, otherwise the audio should be routed via HDMI.
The problem is that the jack sensing only works when the codec is actively playing something, that is when the bias set for the codec is not SND_SOC_BIAS_OFF. When the codec is suspended and it is powered off I'm not able to detect anymore the presence of the jack. Because of this issue actively switching the audio from HDMI to HP when the jack is inserted is not working.
The driver I'm using for the RT5640 in the .set_bias_level hook function among other things is gating the I2S input clock and this seems to prevent the generation of the IRQ signal I'm using to detect the presence/absence of the jack (the culprit here is MX-FA[0] bit for those interested).
I can easily modify the codec driver to avoid gating the I2S clock when the bias is off but this seems in contrast with the whole DAPM principle.
How this is usually supposed to be working?
In situations like this it may be best to report jack status as removed when no BIAS is available for jack detection (since no one is using the codec anyway). The jack status could always be re-detected when BIAS is re-enabled.
Liam
On Wed, Sep 23, 2015 at 05:22:38PM +0100, Liam Girdwood wrote:
- Realtek
And me.
On Tue, 2015-09-22 at 11:18 +0200, Carlo Caione wrote:
The problem is that the jack sensing only works when the codec is actively playing something, that is when the bias set for the codec is not SND_SOC_BIAS_OFF. When the codec is suspended and it is powered off I'm not able to detect anymore the presence of the jack. Because of this issue actively switching the audio from HDMI to HP when the jack is inserted is not working.
How this is usually supposed to be working?
In situations like this it may be best to report jack status as removed when no BIAS is available for jack detection (since no one is using the codec anyway). The jack status could always be re-detected when BIAS is re-enabled.
That can upset userspaces - it means you get things like trying to play a notification tone, starting, realising that a headphone is there and trying to switch on the headphone in the middle of the notification being played back which doesn't tend to work out so well.
What I'd expect the driver to be doing here is enabling whatever it needs to do detection enabled while detection is enabled. There's quite a few examples of this in mainline - look for jack code that has DAPM calls in it.
On Wed, Sep 23, 2015 at 6:37 PM, Mark Brown broonie@kernel.org wrote:
That can upset userspaces - it means you get things like trying to play a notification tone, starting, realising that a headphone is there and trying to switch on the headphone in the middle of the notification being played back which doesn't tend to work out so well.
What I'd expect the driver to be doing here is enabling whatever it needs to do detection enabled while detection is enabled.
What I don't get here is what do you mean with "detection". Can we simply consider PA listening for jack change events a "detection"?
There's quite a few examples of this in mainline - look for jack code that has DAPM calls in it.
Do you thing the rt5670.c could be a good example for that?
In that case a GPIO is used to trigger the jack type detection. The jack change interrupt is notified also when the codec is off/inactive and in the codec the status of the jack (jack_inserted) is detected directly reading from some codec registers. The DAPM calls are used in the code path to determine the type of the jack.
In my case the setup is different though. The GPIO is driven by the codec itself and it doesn't work when the codec BIAS is off. So the problem is that I cannot use the DAPM code since before that I need to find a way to detect the change in the GPIO status when I'm not actively using the codec.
I see two possible solutions for this problem: 1) as said before I can just avoid to turn the BIAS totally off, leaving the I2S clock active that allows the codec to drive the GPIO or 2) keep polling on the status of the GPIO enabling and then disabling the BIAS (or using the DAPM code) just for the time needed to read the GPIO status
Thanks,
On Thu, Sep 24, 2015 at 10:34:14PM +0200, Carlo Caione wrote:
On Wed, Sep 23, 2015 at 6:37 PM, Mark Brown broonie@kernel.org wrote:
That can upset userspaces - it means you get things like trying to play a notification tone, starting, realising that a headphone is there and trying to switch on the headphone in the middle of the notification being played back which doesn't tend to work out so well.
What I'd expect the driver to be doing here is enabling whatever it needs to do detection enabled while detection is enabled.
What I don't get here is what do you mean with "detection". Can we simply consider PA listening for jack change events a "detection"?
Detection is the act of detecting if a jack is physically present in the socket. This will normally happen all the time the system is running, some userspaces rely on uevents to get notifications so the kernel can't tell if anything is listening.
There's quite a few examples of this in mainline - look for jack code that has DAPM calls in it.
Do you thing the rt5670.c could be a good example for that?
No, that doesn't appear to have any interlock with DAPM and is just basic GPIO stuff.
In my case the setup is different though. The GPIO is driven by the codec itself and it doesn't work when the codec BIAS is off. So the problem is that I cannot use the DAPM code since before that I need to find a way to detect the change in the GPIO status when I'm not actively using the codec.
To repeat:
| What I'd expect the driver to be doing here is enabling whatever it | needs to do detection enabled while detection is enabled. There's quite | a few examples of this in mainline - look for jack code that has DAPM | calls in it.
If you need to force things on during detection you should add code to do that, for example enabling relevant DAPM widgets with _force_enable().
I see two possible solutions for this problem: 1) as said before I can just avoid to turn the BIAS totally off, leaving the I2S clock active that allows the codec to drive the GPIO or 2) keep polling on the status of the GPIO enabling and then disabling the BIAS (or using the DAPM code) just for the time needed to read the GPIO status
Enabling things only when needed is of course optimal but you need detection to work whenever detection is enabled. It sounds like this is not the case for your system.
participants (3)
-
Carlo Caione
-
Liam Girdwood
-
Mark Brown