No auto switching in-between front headphone jack and rare jack on FreeBSD OSS

I want to configure jacks in a way that enables switching automatically between front headphone jack and back line-out speaker (subwoofers). Currently, I am running FreeBSD 11.2-RELEASE

For activating the headphone sound, I have to manually issue: sysctl hw.snd.default_unit=1 each time I plug in the headphone jack.

Code:
% cat /dev/sndstat 
Installed devices:
pcm0: <Realtek ALC887 (Rear Analog)> (play/rec) default
pcm1: <Realtek ALC887 (Front Analog)> (play/rec)
No devices installed from userspace.

At this moment, I only have got the sound going through the rare loc Line-out jack or headphones manually via sysctl hw.snd.default_unit=1

I have verbose_boot enabled in loader.conf and I managed to get a verbose boot report like this:

Code:
hdac0: PCI card vendor: 0x1458, device: 0xa002
hdac0: HDA Driver Revision: 20120126_0002
hdac0: Config options: on=0x00000000 off=0x00000000
hdac0: attempting to allocate 1 MSI vectors (1 supported)
hdac0: using IRQ 264 for MSI
hdac0: Caps: OSS 4, ISS 4, BSS 0, NSDO 1, 64bit, CORB 256, RIRB 256
random: harvesting attach, 8 bytes (4 bits) from hdac0
hdacc0: <Realtek ALC887 HDA CODEC> at cad 2 on hdac0
hdaa0: <Realtek ALC887 Audio Function Group> at nid 1 on hdacc0
hdaa0: Subsystem ID: 0x1458a002
hdaa0: NumGPIO=2 NumGPO=0 NumGPI=0 GPIWake=0 GPIUnsol=1
hdaa0:  GPIO0: disabled
hdaa0:  GPIO1: disabled
hdaa0: Original pins configuration:
hdaa0: nid   0x    as seq device       conn  jack    loc        color   misc
hdaa0: 17 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: 18 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: 20 01014410 1  0  Line-out      Jack  1/8     Rear       Green   4
hdaa0: 21 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: 22 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: 23 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: 24 01a19c50 5  0  Mic           Jack  1/8     Rear       Pink    12
hdaa0: 25 02a19c60 6  0  Mic           Jack  1/8     Front      Pink    12
hdaa0: 26 0181345f 5  15 Line-in       Jack  1/8     Rear       Blue    4
hdaa0: 27 02214c20 2  0  Headphones    Jack  1/8     Front      Green   12
hdaa0: 28 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: 29 4004c601 0  1  Line-out      None  RCA     0x00       Res.C   6
hdaa0: 30 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: 31 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa0: Patching widget caps nid=29 0x00400400 -> 0x00700400
hdaa0: Patched pins configuration:
hdaa0: nid   0x    as seq device       conn  jack    loc        color   misc
hdaa0: 17 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 18 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 20 01014410 1  0  Line-out      Jack  1/8     Rear       Green   4
hdaa0: 21 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 22 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 23 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 24 01a19c50 5  0  Mic           Jack  1/8     Rear       Pink    12
hdaa0: 25 02a19c60 6  0  Mic           Jack  1/8     Front      Pink    12
hdaa0: 26 0181345f 5  15 Line-in       Jack  1/8     Rear       Blue    4
hdaa0: 27 02214c20 2  0  Headphones    Jack  1/8     Front      Green   12
hdaa0: 28 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 30 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 31 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 4 associations found:
hdaa0: Association 0 (1) out:
hdaa0:  Pin nid=20 seq=0
hdaa0: Association 1 (2) out:
hdaa0:  Pin nid=27 seq=0
hdaa0: Association 2 (5) in: 
hdaa0:  Pin nid=24 seq=0
hdaa0:  Pin nid=26 seq=15
hdaa0: Association 3 (6) in: 
hdaa0:  Pin nid=25 seq=0
hdaa0: Tracing association 0 (1) 
hdaa0:  Pin 20 traced to DAC 2
hdaa0: Association 0 (1) trace succeeded
hdaa0: Tracing association 1 (2) 
hdaa0:  Pin 27 traced to DAC 3
hdaa0: Association 1 (2) trace succeeded
hdaa0: Tracing association 2 (5) 
hdaa0:  Pin 24 traced to ADC 8
hdaa0:  Pin 26 traced to ADC 8
hdaa0: Association 2 (5) trace succeeded
hdaa0: Tracing association 3 (6) 
hdaa0:  Pin 25 traced to ADC 9
hdaa0: Association 3 (6) trace succeeded
hdaa0: Looking for additional DAC for association 0 (1) 
hdaa0: Looking for additional DAC for association 1 (2) 
hdaa0: Looking for additional ADC for association 2 (5) 
hdaa0: Looking for additional ADC for association 3 (6) 
hdaa0: Tracing input monitor
hdaa0:  Tracing nid 11 to out 
hdaa0:  nid 11 is input monitor
hdaa0:  Tracing nid 34 to out 
hdaa0:  Tracing nid 35 to out 
hdaa0: Tracing other input monitors
hdaa0:  Tracing nid 24 to out 
hdaa0:  Tracing nid 25 to out 
hdaa0:  Tracing nid 26 to out 
hdaa0: Tracing beeper
hdaa0: Pin sense: nid=20 sense=0x80000000 (connected)
hdaa0: FG config/quirks: forcestereo ivref50 ivref80 ivref100 ivref
pcm0: <Realtek ALC887 (Rear Analog)> at nid 20 and 24,26 on hdaa0
pcm1: <Realtek ALC887 (Front Analog)> at nid 27 and 25 on hdaa0
random: harvesting attach, 8 bytes (4 bits) from hdaa0
random: harvesting attach, 8 bytes (4 bits) from hdacc0
hdac0: <Intel Cougar Point HDA Controller> mem 0xf7c00000-0xf7c03fff irq 22 at device 27.0 on pci0
hdac0: PCI card vendor: 0x1458, device: 0xa002
hdac0: HDA Driver Revision: 20120126_0002
hdac0: Config options: on=0x00000000 off=0x00000000
hdac0: attempting to allocate 1 MSI vectors (1 supported)
hdac0: using IRQ 264 for MSI 
hdac0: Caps: OSS 4, ISS 4, BSS 0, NSDO 1, 64bit, CORB 256, RIRB 256 
random: harvesting attach, 8 bytes (4 bits) from hdac0
hdacc0: <Realtek ALC887 HDA CODEC> at cad 2 on hdac0
hdaa0: <Realtek ALC887 Audio Function Group> at nid 1 on hdacc0
hdaa0: Subsystem ID: 0x1458a002
hdaa0: NumGPIO=2 NumGPO=0 NumGPI=0 GPIWake=0 GPIUnsol=1
hdaa0:  GPIO0: disabled
hdaa0:  GPIO1: disabled
hdaa0: Original pins configuration:
hdaa0: nid   0x    as seq device       conn  jack    loc        color   misc
hdaa0: 17 411111f0 15 0  Speaker       None  1/8     Rear       Black   1   
hdaa0: 18 411111f0 15 0  Speaker       None  1/8     Rear       Black   1   
hdaa0: 20 01014410 1  0  Line-out      Jack  1/8     Rear       Green   4   
hdaa0: 21 411111f0 15 0  Speaker       None  1/8     Rear       Black   1   
hdaa0: 22 411111f0 15 0  Speaker       None  1/8     Rear       Black   1   
hdaa0: 23 411111f0 15 0  Speaker       None  1/8     Rear       Black   1   
hdaa0: 24 01a19c50 5  0  Mic           Jack  1/8     Rear       Pink    12  
hdaa0: 25 02a19c60 6  0  Mic           Jack  1/8     Front      Pink    12  
hdaa0: 26 0181345f 5  15 Line-in       Jack  1/8     Rear       Blue    4   
hdaa0: 27 02214c20 2  0  Headphones    Jack  1/8     Front      Green   12  
hdaa0: 28 411111f0 15 0  Speaker       None  1/8     Rear       Black   1   
hdaa0: 29 4004c601 0  1  Line-out      None  RCA     0x00       Res.C   6   
hdaa0: 30 411111f0 15 0  Speaker       None  1/8     Rear       Black   1   
hdaa0: 31 411111f0 15 0  Speaker       None  1/8     Rear       Black   1   
hdaa0: Patching widget caps nid=29 0x00400400 -> 0x00700400
hdaa0: Patched pins configuration:
hdaa0: nid   0x    as seq device       conn  jack    loc        color   misc
hdaa0: 17 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 18 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 20 01014410 1  0  Line-out      Jack  1/8     Rear       Green   4   
hdaa0: 21 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 22 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 23 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 24 01a19c50 5  0  Mic           Jack  1/8     Rear       Pink    12  
hdaa0: 25 02a19c60 6  0  Mic           Jack  1/8     Front      Pink    12  
hdaa0: 26 0181345f 5  15 Line-in       Jack  1/8     Rear       Blue    4   
hdaa0: 27 02214c20 2  0  Headphones    Jack  1/8     Front      Green   12  
hdaa0: 28 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 30 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 31 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa0: 4 associations found:
hdaa0: Association 0 (1) out:
hdaa0:  Pin nid=20 seq=0
hdaa0: Association 1 (2) out:
hdaa0:  Pin nid=27 seq=0
hdaa0: Association 2 (5) in: 
hdaa0:  Pin nid=24 seq=0
hdaa0:  Pin nid=26 seq=15
hdaa0: Association 3 (6) in: 
hdaa0:  Pin nid=25 seq=0
hdaa0: Tracing association 0 (1) 
hdaa0:  Pin 20 traced to DAC 2
hdaa0: Association 0 (1) trace succeeded
hdaa0: Tracing association 1 (2) 
hdaa0:  Pin 27 traced to DAC 3
hdaa0: Association 1 (2) trace succeeded
hdaa0: Tracing association 2 (5) 
hdaa0:  Pin 24 traced to ADC 8
hdaa0:  Pin 26 traced to ADC 8
hdaa0: Association 2 (5) trace succeeded
hdaa0: Tracing association 3 (6) 
hdaa0:  Pin 25 traced to ADC 9
hdaa0: Association 3 (6) trace succeeded
hdaa0: Looking for additional DAC for association 0 (1) 
hdaa0: Looking for additional DAC for association 1 (2) 
hdaa0: Looking for additional ADC for association 2 (5) 
hdaa0: Looking for additional ADC for association 3 (6) 
hdaa0: Tracing input monitor
hdaa0:  Tracing nid 11 to out 
hdaa0:  nid 11 is input monitor
hdaa0:  Tracing nid 34 to out 
hdaa0:  Tracing nid 35 to out 
hdaa0: Tracing other input monitors
hdaa0:  Tracing nid 24 to out 
hdaa0:  Tracing nid 25 to out 
hdaa0:  Tracing nid 26 to out 
hdaa0: Tracing beeper
hdaa0: Pin sense: nid=20 sense=0x80000000 (connected)
hdaa0: FG config/quirks: forcestereo ivref50 ivref80 ivref100 ivref
pcm0: <Realtek ALC887 (Rear Analog)> at nid 20 and 24,26 on hdaa0
pcm1: <Realtek ALC887 (Front Analog)> at nid 27 and 25 on hdaa0
ata4: random: harvesting attach, 8 bytes (4 bits) from hdaa0
ata4: random: harvesting attach, 8 bytes (4 bits) from hdacc0


Now according to snd_hda(4) manpage:

The nid, as, seq of my headphone, is 27, 2, 0 respectively, and for the back (rare jack) subwoofer of my CPU, nid, as, seq is 20, 1, 0 respectively.

So I sudoedit /boot/device.hints and added this following line:

Code:
hint.hdaa.0.nid27.config="as=1 seq=0 device=Headphones"
and shutdown -r now

After reboot, I expect my headphone jack to work (i.e produce sound through it), but it still the same (no sound from there). The subwoofer (rare Line-out) produces sound, but headphone still requires ' sysctl hw.snd.default_unit=1 to work as expected.

What I am missing?

I also tried this thread but not much help.

Additional info:

/etc/sysct.conf

Code:
vfs.zfs.min_auto_ashift=12
vfs.usermount=1
net.local.stream.recvspace=16384
kern.ipc.shm_allow_removed=1

rc.conf

Code:
zfs_enable="YES"
dbus_enable="YES"
devd_enable="YES"
mixer_enable="YES"
devfs_rulesets="localrules system"
clear_tmp_enable="YES"
kld_list="i915kms"

loader.conf

Code:
kern.geom.label.disk_ident.enable="0"
kern.geom.label.gptid.enable="0"
zfs_load="YES"
boot_verbose=1
sound_load="YES"
snd_driver_load="YES"
snd_hda_load="YES"
 
I'm disappointed that nobody took a look. After suffering from this issue since 2018 till today, I've managed to make it less painful with a Perl script (yes, Perl). The script begins by checking if it is being run with root privileges and whether the `snd_hda` audio driver is loaded, using `sysctl` to query kernel modules. It then retrieves the Node ID (NID) of the headphone jack by executing the command `hdajackretask --list` and parsing its output. Once the headphone NID is found, it appends a configuration hint to `/boot/device.hints` using `open` and `write`, specifying the audio settings for headphones. The program enters an infinite loop where it monitors the jack status by reading from `/dev/sndstat`, checking if the headphones (pcm1 device) are connected. If headphones are plugged in, it sets the default sound output to unit 1 (headphones) using another `sysctl` call. If they are unplugged, it switches back to unit 0 (line-out). The check is repeated every 2 seconds using the `sleep` function.

Perl:
#!/usr/bin/perl

use strict;
use warnings;
use POSIX qw(geteuid);
use File::Copy;

my $SND_DEFAULT_UNIT = 'hw.snd.default_unit';
my $SNDSTAT = '/dev/sndstat';
my $DEVICE_HINTS = '/boot/device.hints';

my $HEADPHONE_NID = "0";

sub check_root {
    if (geteuid() != 0) {
        die "This script requires root privileges.\n";
    }
}

sub check_hda_driver {
    my $kldstat_output = `kldstat`;
    die "snd_hda driver is not loaded.\n" unless $kldstat_output =~ /snd_hda/;
}

sub get_headphone_nid {
    my $output = `hdajackretask --list`;
    die "Headphone jack not found.\n" unless $output =~ /Headphones.*\s(\d+)/;
    $HEADPHONE_NID = $1;
}

sub write_device_hint {
    open my $fh, '<', $DEVICE_HINTS or die "Cannot open $DEVICE_HINTS: $!";
    while (<$fh>) {
        return if /nid$HEADPHONE_NID/;
    }
    close $fh;

    open $fh, '>>', $DEVICE_HINTS or die "Cannot open $DEVICE_HINTS for writing: $!";
    print $fh "hint.hdaa.0.nid$HEADPHONE_NID.config=\"as=1 seq=0 device=Headphones default\"\n";
    close $fh;
}

sub get_default_unit {
    chomp(my $unit = `sysctl -n $SND_DEFAULT_UNIT`);
    return $unit;
}

sub set_default_unit {
    my ($unit) = @_;
    system("sysctl $SND_DEFAULT_UNIT=$unit") == 0 or die "Failed to set $SND_DEFAULT_UNIT\n";
}

sub get_jack_status {
    open my $fh, '<', $SNDSTAT or die "Cannot open $SNDSTAT: $!";
    while (<$fh>) {
        if (/pcm1:.*<Headphones>/) {
            close $fh;
            return 1;
        }
    }
    close $fh;
    return 0;
}

sub main_loop {
    my $current_unit = get_default_unit();

    while (1) {
        my $jack_status = get_jack_status();

        if ($jack_status && $current_unit != 1) {
            set_default_unit(1);
            $current_unit = 1;
            print "Switched to Headphones\n";
        } elsif (!$jack_status && $current_unit != 0) {
            set_default_unit(0);
            $current_unit = 0;
            print "Switched to Line-out\n";
        }

        sleep 2;
    }
}

check_root();
check_hda_driver();
get_headphone_nid();
write_device_hint();
main_loop();
 
The nid, as, seq of my headphone, is 27, 2, 0 respectively, and for the back (rare jack) subwoofer of my CPU, nid, as, seq is 20, 1, 0 respectively.

So I sudoedit /boot/device.hints and added this following line:

Code:
hint.hdaa.0.nid27.config="as=1 seq=0 device=Headphones"

You were almost there. hint.hdaa.0.nid27.config="as=1 seq=15" should do the trick.
 
Back
Top