mbox series

[RFC,0/2] design a way to change audio Jack state by software

Message ID 20201209124344.219158-1-hui.wang@canonical.com (mailing list archive)
Headers show
Series design a way to change audio Jack state by software | expand

Message

Hui Wang Dec. 9, 2020, 12:43 p.m. UTC
After we change sth in the userspace audio stack like alsa-ucm or
pulseaudio, we want to perform remote audio auto test to verify if the
change introduce the regression or not, some of the tests are about
the defaut_sink/default_source or active_port switching, this needs
the audio jack state to be changed to trigger the userspace's audio
device switching.

So far, there is no software ways to change the audio jack state, this
block the auto test.

My design is adding a sysfs interface for each sound card if the card
has audio jack, then users could echo different values to sysfs to
change the jack state (Phantom jack is not controlled by injection).
And once the users enable the jack injection via sysfs, this jack's
state will not be controlled by hw events anymore until users disable
the jack injection.

Of course, this could not 100% simulate the plugin or plugout triggered
by hw events, with the hw triggered plugin or plugout, the audio driver
will set codec or does sth else, so the software injection is just
changing the jack state and notify the userspace, it is just for
testing userspace part.

Here is an example to change jack state via sysfs:

After booting up:
/* cd to the jack injection folder for sound card0 in the sysfs */
$cd /sys/devices/pci0000:00/0000:00:1f.3/skl_hda_dsp_generic/sound/card0/jack

/* check file nodes in this folder */
$ls
jackin_inject  sw_inject_enable

/* check all jack's software injection enable status, all disabled now */
$ cat sw_inject_enable 
Jack: Mic  0
Jack: Headphone  0
Jack: HDMI/DP,pcm=3  0
Jack: HDMI/DP,pcm=4  0
Jack: HDMI/DP,pcm=5  0

/* enable software injection for Jack Headphone */
$ sudo sh -c "echo Headphone 1 > sw_inject_enable"

/* check all jack's software injection enable status again, now Headphone is enabled */
$ cat sw_inject_enable 
Jack: Mic  0
Jack: Headphone  1
Jack: HDMI/DP,pcm=3  0
Jack: HDMI/DP,pcm=4  0
Jack: HDMI/DP,pcm=5  0

/* trigger plugin to Jack Headphone */
$sudo sh -c "echo Headphone 1 > jackin_inject"

/* check if Jack Headphone is plugged in */
$ sudo amixer contents | grep "Headphone Jack" -3
numid=30,iface=CARD,name='HDMI/DP,pcm=5 Jack'
  ; type=BOOLEAN,access=r-------,values=1
  : values=off
numid=17,iface=CARD,name='Headphone Jack'
  ; type=BOOLEAN,access=r-------,values=1
  : values=on
numid=14,iface=CARD,name='Mic Jack'

/* trigger plugout to Jack Headphone */
$ sudo sh -c "echo Headphone 0 > jackin_inject"

/* check if Jack Headphone is plugged out */
$ sudo amixer contents | grep "Headphone Jack" -3
numid=30,iface=CARD,name='HDMI/DP,pcm=5 Jack'
  ; type=BOOLEAN,access=r-------,values=1
  : values=off
numid=17,iface=CARD,name='Headphone Jack'
  ; type=BOOLEAN,access=r-------,values=1
  : values=off
numid=14,iface=CARD,name='Mic Jack'

/* disable Jack Headphone software injection, this will return the control to non-injection ways */
$ sudo sh -c "echo Headphone 0 > sw_inject_enable"

/* check if the Jack Headphone software injection is disabled, it is disabled now */
$ cat sw_inject_enable 
Jack: Mic  0
Jack: Headphone  0
Jack: HDMI/DP,pcm=3  0
Jack: HDMI/DP,pcm=4  0
Jack: HDMI/DP,pcm=5  0

Hui Wang (2):
  alsa: jack: expand snd_jack_report parameter for jack sw_inject
  alsa: jack: adding support for software jack in or out injection

 include/sound/core.h            |   1 +
 include/sound/jack.h            |   5 +-
 sound/core/jack.c               | 129 +++++++++++++++++++++++++++++++-
 sound/pci/hda/hda_jack.c        |   6 +-
 sound/pci/hda/patch_hdmi.c      |   2 +-
 sound/pci/oxygen/xonar_wm87x6.c |   2 +-
 sound/soc/soc-jack.c            |   2 +-
 sound/x86/intel_hdmi_audio.c    |   4 +-
 8 files changed, 140 insertions(+), 11 deletions(-)

Comments

Jaroslav Kysela Dec. 9, 2020, 2:25 p.m. UTC | #1
Dne 09. 12. 20 v 13:43 Hui Wang napsal(a):
> After we change sth in the userspace audio stack like alsa-ucm or
> pulseaudio, we want to perform remote audio auto test to verify if the
> change introduce the regression or not, some of the tests are about
> the defaut_sink/default_source or active_port switching, this needs
> the audio jack state to be changed to trigger the userspace's audio
> device switching.
> 
> So far, there is no software ways to change the audio jack state, this
> block the auto test.

I'm not convinced to pollute the kernel space with this code. You can use
LD_PRELOAD and simulate this via a shared library or the alsa-lib may be extended.

Also, the first patch can be omitted if you just create another
snd_jack_report() function for the user API and put the common code to the
static function in jack.c.

					Jaroslav
Takashi Iwai Dec. 9, 2020, 2:44 p.m. UTC | #2
On Wed, 09 Dec 2020 15:25:42 +0100,
Jaroslav Kysela wrote:
> 
> Dne 09. 12. 20 v 13:43 Hui Wang napsal(a):
> > After we change sth in the userspace audio stack like alsa-ucm or
> > pulseaudio, we want to perform remote audio auto test to verify if the
> > change introduce the regression or not, some of the tests are about
> > the defaut_sink/default_source or active_port switching, this needs
> > the audio jack state to be changed to trigger the userspace's audio
> > device switching.
> > 
> > So far, there is no software ways to change the audio jack state, this
> > block the auto test.
> 
> I'm not convinced to pollute the kernel space with this code. You can use
> LD_PRELOAD and simulate this via a shared library or the alsa-lib may be extended.

While I understand this argument, I see the merit of having the
kernel-side injection, too.  Wrapping with LD_PRELOAD (or use alsa-lib
plugin) doesn't verify whether the whole jack system works.  OTOH, the
jack injection in kernel simulates the closer path to the real use
case, which covers also the call paths inside the kernel.

Though, I'm not sure whether the current design is the best choice.
Basically sysfs is expressed in one value per file (although there are
many exceptions, of course).  So creating a node per jack object might
fit better?  Or can it better be in debugfs?

> Also, the first patch can be omitted if you just create another
> snd_jack_report() function for the user API and put the common code to the
> static function in jack.c.

Fully agreed on this point.


thanks,

Takashi
Hui Wang Dec. 10, 2020, 1:54 a.m. UTC | #3
On 12/9/20 10:44 PM, Takashi Iwai wrote:
> On Wed, 09 Dec 2020 15:25:42 +0100,
> Jaroslav Kysela wrote:
>> Dne 09. 12. 20 v 13:43 Hui Wang napsal(a):
>>> After we change sth in the userspace audio stack like alsa-ucm or
>>> pulseaudio, we want to perform remote audio auto test to verify if the
>>> change introduce the regression or not, some of the tests are about
>>> the defaut_sink/default_source or active_port switching, this needs
>>> the audio jack state to be changed to trigger the userspace's audio
>>> device switching.
>>>
>>> So far, there is no software ways to change the audio jack state, this
>>> block the auto test.
>> I'm not convinced to pollute the kernel space with this code. You can use
>> LD_PRELOAD and simulate this via a shared library or the alsa-lib may be extended.
> While I understand this argument, I see the merit of having the
> kernel-side injection, too.  Wrapping with LD_PRELOAD (or use alsa-lib
> plugin) doesn't verify whether the whole jack system works.  OTOH, the
> jack injection in kernel simulates the closer path to the real use
> case, which covers also the call paths inside the kernel.
>
> Though, I'm not sure whether the current design is the best choice.
> Basically sysfs is expressed in one value per file (although there are
> many exceptions, of course).  So creating a node per jack object might
> fit better?  Or can it better be in debugfs?
OK, got it, will investigate it.
>
>> Also, the first patch can be omitted if you just create another
>> snd_jack_report() function for the user API and put the common code to the
>> static function in jack.c.
> Fully agreed on this point.

Indeed, it is a better and cleaner way, will think about it and 
implement it.

Thanks.

>
> thanks,
>
> Takashi
Kai Vehmanen Dec. 11, 2020, 1:36 p.m. UTC | #4
Hi,

On Wed, 9 Dec 2020, Jaroslav Kysela wrote:

> Dne 09. 12. 20 v 13:43 Hui Wang napsal(a):
> > After we change sth in the userspace audio stack like alsa-ucm or
> > pulseaudio, we want to perform remote audio auto test to verify if the
> > change introduce the regression or not, some of the tests are about
> > the defaut_sink/default_source or active_port switching, this needs

thanks Hui for the RFC.

I do think this is a very tempting capability to add. I understand 
Jaroslav's concerns as well, but there is clearly a category of issues 
where user-space functionality is broken due to a mismatch of element 
names between UCM file and the driver. I.e. the actual jack detection 
(codec hw and its driver) is working, but due to wrong UCM file chosen, 
wrong driven is chosen, or errors in either UCM or driver, event does not 
get parsed right and user ends with no audio.

A pure user-space test harness would not catch these, and building full 
automation of external codec events, is a complex task and coverage of 
devices is likely limited. 

The 'edid_override' debugfs interface in i915 is a bit similar. It allows
inject EDID content irrespectively of the actual monitor connected.

> Also, the first patch can be omitted if you just create another
> snd_jack_report() function for the user API and put the common code to the
> static function in jack.c.

++votes on this

Br, Kai
Hui Wang Dec. 14, 2020, 10:48 a.m. UTC | #5
On 12/11/20 9:36 PM, Kai Vehmanen wrote:
> Hi,
>
> On Wed, 9 Dec 2020, Jaroslav Kysela wrote:
>
>> Dne 09. 12. 20 v 13:43 Hui Wang napsal(a):
>>> After we change sth in the userspace audio stack like alsa-ucm or
>>> pulseaudio, we want to perform remote audio auto test to verify if the
>>> change introduce the regression or not, some of the tests are about
>>> the defaut_sink/default_source or active_port switching, this needs
> thanks Hui for the RFC.
>
> I do think this is a very tempting capability to add. I understand
> Jaroslav's concerns as well, but there is clearly a category of issues
> where user-space functionality is broken due to a mismatch of element
> names between UCM file and the driver. I.e. the actual jack detection
> (codec hw and its driver) is working, but due to wrong UCM file chosen,
> wrong driven is chosen, or errors in either UCM or driver, event does not
> get parsed right and user ends with no audio.
>
> A pure user-space test harness would not catch these, and building full
> automation of external codec events, is a complex task and coverage of
> devices is likely limited.
>
> The 'edid_override' debugfs interface in i915 is a bit similar. It allows
> inject EDID content irrespectively of the actual monitor connected.
>
>> Also, the first patch can be omitted if you just create another
>> snd_jack_report() function for the user API and put the common code to the
>> static function in jack.c.
> ++votes on this
OK, got it,  am preparing the v2 RFC, will send it out soon. Thanks for 
your comment.
>
> Br, Kai