[alsa-devel] configuring machine specific DAPM for codec + headset jack detect
Greetings,
I have a TI TLV320AIC3105 codec on a board connected to a TS3A227E headset detect chip (which handles switching pins for OMTP vs std jacks as well as jack detect and headset buttons). The AIC3105 doesn't use several of the inputs and outputs yet those inputs and outputs still have mux widgets volume widgets that are not 'off'.
Is there a way to easily disable them so they a) are not muxed into mixers, b) have their gains set to 0, and c) are pruned from the list of widgets so users don't have to muddle through them in mixers?
I am also fighting both a pop/click issue and am wondering if there is any easy way to disable the DAPM power up/down sequence upon playback start/complete (my application is not power sensitive). I'm still trying to understand the source of the pop/click.
Additionally the TS3A227E requires MIC bias to be kept enabled in order to detect headset button presses. I see that setting idle_bias_off to false will keep the MIC bias enabled but I don't see a way to specify that via device-tree.
Regards,
Tim
On Mon, Oct 17, 2016 at 04:33:10PM -0700, Tim Harvey wrote:
I have a TI TLV320AIC3105 codec on a board connected to a TS3A227E headset detect chip (which handles switching pins for OMTP vs std jacks as well as jack detect and headset buttons). The AIC3105 doesn't use several of the inputs and outputs yet those inputs and outputs still have mux widgets volume widgets that are not 'off'.
Is there a way to easily disable them so they a) are not muxed into mixers, b) have their gains set to 0, and c) are pruned from the list of widgets so users don't have to muddle through them in mixers?
No, you need to write that code if you want it - we do mark not connected things with the intention that someone could implement this but nobody did yet.
I am also fighting both a pop/click issue and am wondering if there is any easy way to disable the DAPM power up/down sequence upon playback start/complete (my application is not power sensitive). I'm still trying to understand the source of the pop/click.
You can ramp the power down time up but no, there's no way to disable it completely in the kernel - this is normally done in the sound server and tends to work better that way as starting and stopping the digital audio stream tends to be glitchy.
Additionally the TS3A227E requires MIC bias to be kept enabled in order to detect headset button presses. I see that setting idle_bias_off to false will keep the MIC bias enabled but I don't see a way to specify that via device-tree.
Your machine driver should force enable any widgets it needs. idle_bias_off should have no effect on microphone biases, if it does that sounds like a bug.
On Tue, Oct 18, 2016 at 4:02 AM, Mark Brown broonie@kernel.org wrote:
On Mon, Oct 17, 2016 at 04:33:10PM -0700, Tim Harvey wrote:
I have a TI TLV320AIC3105 codec on a board connected to a TS3A227E headset detect chip (which handles switching pins for OMTP vs std jacks as well as jack detect and headset buttons). The AIC3105 doesn't use several of the inputs and outputs yet those inputs and outputs still have mux widgets volume widgets that are not 'off'.
Is there a way to easily disable them so they a) are not muxed into mixers, b) have their gains set to 0, and c) are pruned from the list of widgets so users don't have to muddle through them in mixers?
No, you need to write that code if you want it - we do mark not connected things with the intention that someone could implement this but nobody did yet.
Hi Mark,
OK - that explains why 'snd_soc_dapm_disable_pin' and 'snd_soc_dapm_enable_pin' didn't have any noticeable affect when I was calling those from a machine driver. I will plan on having to setup all the ALSA controls manually in my OS configuration (Android in this use case using tinyalsa_hal).
I am also fighting both a pop/click issue and am wondering if there is any easy way to disable the DAPM power up/down sequence upon playback start/complete (my application is not power sensitive). I'm still trying to understand the source of the pop/click.
You can ramp the power down time up but no, there's no way to disable it completely in the kernel - this is normally done in the sound server and tends to work better that way as starting and stopping the digital audio stream tends to be glitchy.
I haven't found where the power down time is specified/configured - can you point me to that?
Additionally the TS3A227E requires MIC bias to be kept enabled in order to detect headset button presses. I see that setting idle_bias_off to false will keep the MIC bias enabled but I don't see a way to specify that via device-tree.
Your machine driver should force enable any widgets it needs. idle_bias_off should have no effect on microphone biases, if it does that sounds like a bug.
I have found the debuffs dapm_pop_time which I assume is intended to help kernel devs find causes for pop's and it has helped me identify where the pop occurs in the tlv320aic3x.c driver.
In my case I hear a pop at: [ 402.958518] tlv320aic3x-codec 2-0018: pop test : Queue Left HP Mixer: reg=0xffffffff, 0x1/0x1 [ 402.967170] tlv320aic3x-codec 2-0018: pop test : Queue Right HP Mixer: reg=0xffffffff, 0x1/0x1 [ 402.976351] tlv320aic3x-codec 2-0018: pop test : Queue Left HP Out: reg=0x33, 0x1/0x1 [ 402.984243] tlv320aic3x-codec 2-0018: pop test : Applying 0x1/0x1 to 33 in 2000ms [ 405.031626] tlv320aic3x-codec 2-0018: 33 <= 0d
The pop occurs whe HPLOUT Output Level Control Register (Register 51) bit 0 is set indicating 'HPLOUT is fully powered up' and the same can be heard when HPLROUT Register 65 bit 0 is set for the right side.
I'm not quite understanding the DAPM widgets in the driver. These registers are configured by: SND_SOC_DAPM_PGA("Left HP Out", HPLOUT_CTRL, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("Right HP Out", HPROUT_CTRL, 0, 0, NULL, 0),
yet those don't show up in amixer as controls so they are somehow used internally.
Looking at the tlv32aic3105 datasheet (http://www.ti.com/lit/ds/symlink/tlv320aic3105.pdf) Register 51 (0x33) has its mute control in bit3 so I would expect that bit to be cleared before and set after applying this stuff. Is there a missing SND_SOC_DAPM* in that driver perhaps?
Incidentally, the board I'm working with has a DC biased headphone. If I modify the board to AC bias the headphone the pop goes away, but I'm thinking that isn't really the right solution and that there is something instead missing from the tlv320aic3x.c driver that should be muting/unmuting the outputs around the above register changes.
Regarding the ts3a227e headset detect/config switch (http://www.ti.com/lit/ds/symlink/ts3a227e.pdf), what is the proper way to hook that into the Linux input layer via the simple-sound-card driver? The ts3a227e_enable_jack_detect function exported from the ts3a227e.c driver is only currently called by two machine drivers that have explicit support. I suppose if I want to add support for this using simple-sound-card I would need to add a custom dt binding to that driver?
Regards,
Tim
On Tue, Oct 18, 2016 at 11:16:40AM -0700, Tim Harvey wrote:
On Tue, Oct 18, 2016 at 4:02 AM, Mark Brown broonie@kernel.org wrote:
No, you need to write that code if you want it - we do mark not connected things with the intention that someone could implement this but nobody did yet.
OK - that explains why 'snd_soc_dapm_disable_pin' and 'snd_soc_dapm_enable_pin' didn't have any noticeable affect when I was calling those from a machine driver. I will plan on having to setup all the ALSA controls manually in my OS configuration (Android in this use case using tinyalsa_hal).
No, those do useful things with DAPM but not what you're looking for. For things that are disconnected you want _nc_pin().
You can ramp the power down time up but no, there's no way to disable it completely in the kernel - this is normally done in the sound server and tends to work better that way as starting and stopping the digital audio stream tends to be glitchy.
I haven't found where the power down time is specified/configured - can you point me to that?
pmdown_time.
I'm not quite understanding the DAPM widgets in the driver. These registers are configured by: SND_SOC_DAPM_PGA("Left HP Out", HPLOUT_CTRL, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("Right HP Out", HPROUT_CTRL, 0, 0, NULL, 0),
yet those don't show up in amixer as controls so they are somehow used internally.
DAPM widgets are not controls, they're purely internal to the kernel. The kernel will power up any DAPM widgets that form part of a complete audio path from input to output or which are forced on.
Looking at the tlv32aic3105 datasheet (http://www.ti.com/lit/ds/symlink/tlv320aic3105.pdf) Register 51 (0x33) has its mute control in bit3 so I would expect that bit to be cleared before and set after applying this stuff. Is there a missing SND_SOC_DAPM* in that driver perhaps?
You *can* hook mutes into DAPM with _AUTODISABLE controls but it's rarely required.
Incidentally, the board I'm working with has a DC biased headphone. If I modify the board to AC bias the headphone the pop goes away, but I'm thinking that isn't really the right solution and that there is something instead missing from the tlv320aic3x.c driver that should be muting/unmuting the outputs around the above register changes.
I'm not sure what you mean by DC and AC bias here, sorry. Do you mean VMID referenced vs ground referenced? If it's that then it sounds like the driver ought to be biasing the headphones in set_bias_level() probably based on some DT information, though I'd also say that I can't think of any reason why you wouldn't want ground referenced outputs so perhaps I'm missing something.
Regarding the ts3a227e headset detect/config switch (http://www.ti.com/lit/ds/symlink/ts3a227e.pdf), what is the proper way to hook that into the Linux input layer via the simple-sound-card driver? The ts3a227e_enable_jack_detect function exported from the ts3a227e.c driver is only currently called by two machine drivers that have explicit support. I suppose if I want to add support for this using simple-sound-card I would need to add a custom dt binding to that driver?
There was a thread a while back where Dylan Reid proposed a custom jack binding ("Add a gpio jack device" IIRC) but that ground to a halt. Right now I'd expect a custom machine driver for something like this which is obviously not ideal but is going to be a lot easier for you to implement.
On Tue, Oct 18, 2016 at 11:30 AM, Mark Brown broonie@kernel.org wrote:
On Tue, Oct 18, 2016 at 11:16:40AM -0700, Tim Harvey wrote:
<snip>
I'm not quite understanding the DAPM widgets in the driver. These registers are configured by: SND_SOC_DAPM_PGA("Left HP Out", HPLOUT_CTRL, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("Right HP Out", HPROUT_CTRL, 0, 0, NULL, 0),
yet those don't show up in amixer as controls so they are somehow used internally.
Ok, I see how the routing maps these together.
DAPM widgets are not controls, they're purely internal to the kernel. The kernel will power up any DAPM widgets that form part of a complete audio path from input to output or which are forced on.
Looking at the tlv32aic3105 datasheet (http://www.ti.com/lit/ds/symlink/tlv320aic3105.pdf) Register 51 (0x33) has its mute control in bit3 so I would expect that bit to be cleared before and set after applying this stuff. Is there a missing SND_SOC_DAPM* in that driver perhaps?
You *can* hook mutes into DAPM with _AUTODISABLE controls but it's rarely required.
Can you give me more detail? I'm unable to figure out how to add mute control to the tlv320aic3x.c driver. I would think it would be something like adding:
Register the following DAPM widgets: SND_SOC_DAPM_PGA("Left Mute", HPLOUT_CTRL, 3, 0, NULL, 0), SND_SOC_DAPM_PGA("Right Mute", HPROUT_CTRL, 3, 0, NULL, 0),
Add following to routing: {"HPLOUT", NULL, "Left Mute"}, {"HPROUT", NULL, "Right Mute"},
Incidentally, the board I'm working with has a DC biased headphone. If I modify the board to AC bias the headphone the pop goes away, but I'm thinking that isn't really the right solution and that there is something instead missing from the tlv320aic3x.c driver that should be muting/unmuting the outputs around the above register changes.
I'm not sure what you mean by DC and AC bias here, sorry. Do you mean VMID referenced vs ground referenced? If it's that then it sounds like the driver ought to be biasing the headphones in set_bias_level() probably based on some DT information, though I'd also say that I can't think of any reason why you wouldn't want ground referenced outputs so perhaps I'm missing something.
I mean that the HP out of the codec is directly coupled to the headphone vs via a DC blocking capacitor. The outputs are ground-references (single-ended: HPLCOM and HPRCOM are hooked to GND)
I'm certainly no audio expert but have been told that DC coupled headphones have better quality than AC coupled (which kind of makes sense to me) but when you have DC coupled headphones the headphone goes from 0 to 1.4V abruptly when R51.0 and R65.0 are set. I don't think muting is going to help as I would think it would just move the pop to when the output is un-muted (because the pop is caused by the abrupt DC level change).
Am I missing something obvious here? Would DC biased outputs only make sense in a case where you disable the pmdown_time completely?
Regarding the ts3a227e headset detect/config switch (http://www.ti.com/lit/ds/symlink/ts3a227e.pdf), what is the proper way to hook that into the Linux input layer via the simple-sound-card driver? The ts3a227e_enable_jack_detect function exported from the ts3a227e.c driver is only currently called by two machine drivers that have explicit support. I suppose if I want to add support for this using simple-sound-card I would need to add a custom dt binding to that driver?
There was a thread a while back where Dylan Reid proposed a custom jack binding ("Add a gpio jack device" IIRC) but that ground to a halt. Right now I'd expect a custom machine driver for something like this which is obviously not ideal but is going to be a lot easier for you to implement.
Ok - that makes sense. I will stick with a machine driver.
Thanks,
Tim
participants (2)
-
Mark Brown
-
Tim Harvey