diff --git a/sbin/devd/Makefile b/sbin/devd/Makefile --- a/sbin/devd/Makefile +++ b/sbin/devd/Makefile @@ -47,6 +47,11 @@ HYPERVPACKAGE= hyperv-tools .endif +CONFGROUPS+= HDA +HDADIR= ${DEVDDIR} +HDA+= hda.conf +HDAPACKAGE= hda + .if ${MK_USB} != "no" DEVD+= uath.conf ulpt.conf .endif diff --git a/sbin/devd/devd.conf.5 b/sbin/devd/devd.conf.5 --- a/sbin/devd/devd.conf.5 +++ b/sbin/devd/devd.conf.5 @@ -38,7 +38,7 @@ .\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS .\" SOFTWARE. .\" -.Dd March 6, 2024 +.Dd April 25, 2025 .Dt DEVD.CONF 5 .Os .Sh NAME @@ -638,6 +638,22 @@ for details. .El .Pp +.Bl -column "System" "Subsystem" "1234567" -compact +.Sy "System" Ta Sy "Subsystem" Ta Sy "Type" Ta Sy "Description" +.It Li HDA Ta Ta Ta +Events related to the +.Xr snd_hda 4 +driver. +.It Li HDA Ta Li REDIR Ta Li IN Ta +Redirect input to HDA device specified in +.Pa cdev +variable. +.It Li HDA Ta Li REDIR Ta Li OUT Ta +Redirect output to HDA device specified in +.Pa cdev +variable. +.El +.Pp .\" .\" End of tables .\" diff --git a/sbin/devd/hda.conf b/sbin/devd/hda.conf new file mode 100644 --- /dev/null +++ b/sbin/devd/hda.conf @@ -0,0 +1,18 @@ +# Audio redirection +notify 0 { + match "system" "HDA"; + match "subsystem" "REDIR"; + match "type" "IN"; + match "cdev" "dsp[0-9]+"; + + action "/usr/local/sbin/virtual_oss_cmd /dev/vdsp.ctl -R /dev/$cdev"; +}; + +notify 0 { + match "system" "HDA"; + match "subsystem" "REDIR"; + match "type" "OUT"; + match "cdev" "dsp[0-9]+"; + + action "/usr/local/sbin/virtual_oss_cmd /dev/vdsp.ctl -P /dev/$cdev"; +}; diff --git a/sys/dev/sound/pci/hda/hdaa.c b/sys/dev/sound/pci/hda/hdaa.c --- a/sys/dev/sound/pci/hda/hdaa.c +++ b/sys/dev/sound/pci/hda/hdaa.c @@ -532,9 +532,10 @@ hdaa_presence_handler(struct hdaa_widget *w) { struct hdaa_devinfo *devinfo = w->devinfo; - struct hdaa_audio_as *as; + struct hdaa_audio_as *as, *asp; + char buf[32]; uint32_t res; - int connected, old; + int connected, old, i; if (w->enable == 0 || w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) @@ -552,13 +553,6 @@ if (connected == old) return; w->wclass.pin.connected = connected; - HDA_BOOTVERBOSE( - if (connected || old != 2) { - device_printf(devinfo->dev, - "Pin sense: nid=%d sense=0x%08x (%sconnected)\n", - w->nid, res, !connected ? "dis" : ""); - } - ); as = &devinfo->as[w->bindas]; if (as->hpredir >= 0 && as->pins[15] == w->nid) @@ -567,6 +561,35 @@ hdaa_autorecsrc_handler(as, w); if (old != 2) hdaa_channels_handler(as); + + if (connected || old != 2) { + HDA_BOOTVERBOSE( + device_printf(devinfo->dev, + "Pin sense: nid=%d sense=0x%08x (%sconnected)\n", + w->nid, res, !connected ? "dis" : ""); + ); + if (as->hpredir >= 0) + return; + for (i = 0; i < devinfo->ascnt; i++) { + asp = &devinfo->as[i]; + if (!asp->enable) + continue; + if ((connected && asp->index == as->index) || + (!connected && asp->dir == as->dir)) { + HDA_BOOTVERBOSE( + device_printf(devinfo->dev, + "Redirecting audio to %s\n", + device_get_nameunit( + asp->pdevinfo->dev)); + ); + snprintf(buf, sizeof(buf), "cdev=dsp%d", + device_get_unit(asp->pdevinfo->dev)); + devctl_notify("HDA", "REDIR", + asp->dir == HDAA_CTL_IN ? "IN" : "OUT", buf); + break; + } + } + } } /* @@ -6193,16 +6216,16 @@ device_printf(dev, "Applying direct built-in patches...\n"); ); hdaa_patch_direct(devinfo); - HDA_BOOTHVERBOSE( - device_printf(dev, "Pin sense init...\n"); - ); - hdaa_sense_init(devinfo); HDA_BOOTHVERBOSE( device_printf(dev, "Creating PCM devices...\n"); ); hdaa_unlock(devinfo); hdaa_create_pcms(devinfo); hdaa_lock(devinfo); + HDA_BOOTHVERBOSE( + device_printf(dev, "Pin sense init...\n"); + ); + hdaa_sense_init(devinfo); HDA_BOOTVERBOSE( if (devinfo->quirks != 0) {