Hi! The azalia(4) driver blocks switching between digital and analog converters when media is playing and complains about a busy device. The patch below allows switching converters by disconnecting the streams before switching converters and reconnecting them afterwards. This allows to start audio on analog outputs and switch to digital outputs without having to restart all media, and the other way around.
Please note that I was only able to test the DAC group selection part, because I do not have any input devices connected to my machine (see dmesg below). It would be great if someone with a different azalia(4) device and/or input devices could test the code as well. The patch introduces some new functions in azalia.h that are only used inside azalia_codec.c, but I couldn't find a different way to connect/disconnect the streams from inside the azalia_mixer_set function. Maybe someone has a more elegant way of doing this? Index: azalia.h =================================================================== RCS file: /cvs/src/sys/dev/pci/azalia.h,v retrieving revision 1.62 diff -u -p -r1.62 azalia.h --- azalia.h 10 Sep 2010 15:11:23 -0000 1.62 +++ azalia.h 14 Dec 2014 09:01:03 -0000 @@ -729,3 +729,8 @@ int azalia_mixer_get(const codec_t *, ni int azalia_mixer_set(codec_t *, nid_t, int, const mixer_ctrl_t *); int azalia_codec_enable_unsol(codec_t *); + +int azalia_connect_input(codec_t *); +int azalia_connect_output(codec_t *); +int azalia_disconnect_input(codec_t *); +int azalia_disconnect_output(codec_t *); Index: azalia.c =================================================================== RCS file: /cvs/src/sys/dev/pci/azalia.c,v retrieving revision 1.217 diff -u -p -r1.217 azalia.c --- azalia.c 24 Sep 2014 08:35:12 -0000 1.217 +++ azalia.c 14 Dec 2014 09:01:04 -0000 @@ -2827,6 +2827,18 @@ azalia_codec_add_format(codec_t *this, i } int +azalia_connect_input(codec_t *this) +{ + return azalia_codec_connect_stream(&this->az->rstream); +} + +int +azalia_connect_output(codec_t *this) +{ + return azalia_codec_connect_stream(&this->az->pstream); +} + +int azalia_codec_connect_stream(stream_t *this) { const codec_t *codec = &this->az->codecs[this->az->codecno]; @@ -2900,6 +2912,18 @@ azalia_codec_connect_stream(stream_t *th } return err; +} + +int +azalia_disconnect_input(codec_t *this) +{ + return azalia_codec_disconnect_stream(&this->az->rstream); +} + +int +azalia_disconnect_output(codec_t *this) +{ + return azalia_codec_disconnect_stream(&this->az->pstream); } int Index: azalia_codec.c =================================================================== RCS file: /cvs/src/sys/dev/pci/azalia_codec.c,v retrieving revision 1.165 diff -u -p -r1.165 azalia_codec.c --- azalia_codec.c 10 Dec 2014 14:18:11 -0000 1.165 +++ azalia_codec.c 14 Dec 2014 09:01:05 -0000 @@ -2008,28 +2008,56 @@ azalia_mixer_set(codec_t *this, nid_t ni /* DAC group selection */ else if (target == MI_TARGET_DAC) { - if (this->running) - return EBUSY; + if(this->running) { + err = azalia_disconnect_output(this); + if (err) + return err; + } + if (mc->un.ord >= this->dacs.ngroups) return EINVAL; - if (mc->un.ord != this->dacs.cur) - return azalia_codec_construct_format(this, + + if (mc->un.ord != this->dacs.cur) { + err = azalia_codec_construct_format(this, mc->un.ord, this->adcs.cur); - else - return 0; + if(err) + return err; + + if(this->running) { + err = azalia_connect_output(this); + if (err) + return err; + } + } + + return 0; } /* ADC selection */ else if (target == MI_TARGET_ADC) { - if (this->running) - return EBUSY; + if(this->running) { + err = azalia_disconnect_input(this); + if (err) + return err; + } + if (mc->un.ord >= this->adcs.ngroups) return EINVAL; - if (mc->un.ord != this->adcs.cur) - return azalia_codec_construct_format(this, + + if (mc->un.ord != this->adcs.cur) { + err = azalia_codec_construct_format(this, this->dacs.cur, mc->un.ord); - else - return 0; + if(err) + return err; + + if(this->running) { + err = azalia_connect_input(this); + if (err) + return err; + } + } + + return 0; } /* S/PDIF */ OpenBSD 5.6-current (GENERIC) #22: Sun Dec 14 07:10:11 CET 2014 fno...@zephyr.detrus.org:/usr/src/sys/arch/amd64/compile/GENERIC real mem = 16845033472 (16064MB) avail mem = 16392802304 (15633MB) mpath0 at root scsibus0 at mpath0: 256 targets mainbus0 at root bios0 at mainbus0: SMBIOS rev. 2.6 @ 0xe9500 (103 entries) bios0: vendor American Megatrends Inc. version "1501" date 08/20/2013 bios0: ASUSTeK COMPUTER INC. P8Q67-M DO/TPM acpi0 at bios0: rev 2 acpi0: sleep states S0 S1 S3 S4 S5 acpi0: tables DSDT FACP APIC SSDT MCFG HPET ASF! acpi0: wakeup devices UAR1(S4) PS2K(S4) PS2M(S4) EUSB(S4) USBE(S4) P0P3(S4) P0P4(S4) P0P1(S4) P0P2(S4) PEX0(S4) PEX1(S4) PEX2(S4) PEX3(S4) PEX5(S4) PEX7(S4) GBE_(S4) [...] acpitimer0 at acpi0: 3579545 Hz, 24 bits acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat cpu0 at mainbus0: apid 0 (boot processor) cpu0: Intel(R) Core(TM) i5-2320 CPU @ 3.00GHz, 3000.47 MHz cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,POPCNT,DEADLINE,AES,XSAVE,AVX,NXE,LONG,LAHF,PERF,ITSC cpu0: 256KB 64b/line 8-way L2 cache mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges cpu0: apic clock running at 100MHz cpu at mainbus0: not configured cpu at mainbus0: not configured cpu at mainbus0: not configured ioapic0 at mainbus0: apid 0 pa 0xfec00000, version 20, 24 pins acpimcfg0 at acpi0 addr 0xe0000000, bus 0-63 acpihpet0 at acpi0: 14318179 Hz acpiprt0 at acpi0: bus 0 (PCI0) acpiprt1 at acpi0: bus -1 (P0P3) acpiprt2 at acpi0: bus -1 (P0P4) acpiprt3 at acpi0: bus 1 (P0P1) acpiprt4 at acpi0: bus -1 (P0P2) acpiprt5 at acpi0: bus 2 (PEX0) acpiprt6 at acpi0: bus -1 (PEX1) acpiprt7 at acpi0: bus -1 (PEX2) acpiprt8 at acpi0: bus -1 (PEX3) acpiprt9 at acpi0: bus 3 (PEX7) acpiprt10 at acpi0: bus 4 (BR20) acpicpu0 at acpi0: C3, C2, C1, PSS acpibtn0 at acpi0: PWRB acpivideo0 at acpi0: GFX0 acpivout0 at acpivideo0: DD02 cpu0: Enhanced SpeedStep 3000 MHz: speeds: 3001, 3000, 2900, 2800, 2700, 2600, 2500, 2400, 2300, 2200, 2100, 2000, 1900, 1800, 1700, 1600 MHz pci0 at mainbus0 bus 0 pchb0 at pci0 dev 0 function 0 "Intel Core 2G Host" rev 0x09 ppb0 at pci0 dev 1 function 0 "Intel Core 2G PCIE" rev 0x09: msi pci1 at ppb0 bus 1 vga1 at pci0 dev 2 function 0 "Intel HD Graphics 2000" rev 0x09 intagp at vga1 not configured inteldrm0 at vga1 drm0 at inteldrm0 drm: Memory usable by graphics device = 2048M inteldrm0: 1280x900 wsdisplay0 at vga1 mux 1: console (std, vt100 emulation) wsdisplay0: screen 1-5 added (std, vt100 emulation) "Intel 6 Series MEI" rev 0x04 at pci0 dev 22 function 0 not configured pciide0 at pci0 dev 22 function 2 vendor "Intel", unknown product 0x1c3c rev 0x04: DMA (unsupported), channel 0 wired to native-PCI, channel 1 wired to native-PCI pciide0: using apic 0 int 18 for native-PCI interrupt pciide0: channel 0 ignored (not responding; disabled or no drives?) pciide0: channel 1 ignored (not responding; disabled or no drives?) puc0 at pci0 dev 22 function 3 "Intel 6 Series KT" rev 0x04: ports: 1 com com4 at puc0 port 0 apic 0 int 17: ns16550a, 16 byte fifo com4: probed fifo depth: 0 bytes em0 at pci0 dev 25 function 0 "Intel 82579LM" rev 0x05: msi, address f4:6d:04:e7:0d:56 ehci0 at pci0 dev 26 function 0 "Intel 6 Series USB" rev 0x05: apic 0 int 23 usb0 at ehci0: USB revision 2.0 uhub0 at usb0 "Intel EHCI root hub" rev 2.00/1.00 addr 1 azalia0 at pci0 dev 27 function 0 "Intel 6 Series HD Audio" rev 0x05: msi azalia0: codecs: VIA/0x0397, Intel/0x2805, using VIA/0x0397 audio0 at azalia0 ppb1 at pci0 dev 28 function 0 "Intel 6 Series PCIE" rev 0xb5: msi pci2 at ppb1 bus 2 ppb2 at pci0 dev 28 function 7 "Intel 6 Series PCIE" rev 0xb5: msi pci3 at ppb2 bus 3 ehci1 at pci0 dev 29 function 0 "Intel 6 Series USB" rev 0x05: apic 0 int 23 usb1 at ehci1: USB revision 2.0 uhub1 at usb1 "Intel EHCI root hub" rev 2.00/1.00 addr 1 ppb3 at pci0 dev 30 function 0 "Intel 82801BA Hub-to-PCI" rev 0xa5 pci4 at ppb3 bus 4 pcib0 at pci0 dev 31 function 0 "Intel Q67 LPC" rev 0x05 pciide1 at pci0 dev 31 function 2 "Intel 6 Series SATA" rev 0x05: DMA, channel 0 configured to native-PCI, channel 1 configured to native-PCI pciide1: using apic 0 int 20 for native-PCI interrupt wd0 at pciide1 channel 0 drive 1: <HDS722580VLSA80> wd0: 16-sector PIO, LBA48, 78533MB, 160836480 sectors wd0(pciide1:0:1): using PIO mode 4, Ultra-DMA mode 5 wd1 at pciide1 channel 1 drive 1: <SAMSUNG HD103SJ> wd1: 16-sector PIO, LBA48, 953869MB, 1953525168 sectors wd1(pciide1:1:1): using PIO mode 4, Ultra-DMA mode 6 ichiic0 at pci0 dev 31 function 3 "Intel 6 Series SMBus" rev 0x05: apic 0 int 18 iic0 at ichiic0 spdmem0 at iic0 addr 0x50: 4GB DDR3 SDRAM PC3-10600 spdmem1 at iic0 addr 0x51: 4GB DDR3 SDRAM PC3-10600 spdmem2 at iic0 addr 0x52: 4GB DDR3 SDRAM PC3-10600 spdmem3 at iic0 addr 0x53: 4GB DDR3 SDRAM PC3-10600 pciide2 at pci0 dev 31 function 5 "Intel 6 Series SATA" rev 0x05: DMA, channel 0 wired to native-PCI, channel 1 wired to native-PCI pciide2: using apic 0 int 20 for native-PCI interrupt wd2 at pciide2 channel 0 drive 0: <SAMSUNG HD103SJ> wd2: 16-sector PIO, LBA48, 953869MB, 1953525168 sectors wd2(pciide2:0:0): using PIO mode 4, Ultra-DMA mode 6 wd3 at pciide2 channel 1 drive 0: <SAMSUNG HD103SJ> wd3: 16-sector PIO, LBA48, 953869MB, 1953525168 sectors wd3(pciide2:1:0): using PIO mode 4, Ultra-DMA mode 6 isa0 at pcib0 isadma0 at isa0 com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo pckbc0 at isa0 port 0x60/5 pckbd0 at pckbc0 (kbd slot) pckbc0: using irq 1 for kbd slot wskbd0 at pckbd0: console keyboard, using wsdisplay0 pcppi0 at isa0 port 0x61 spkr0 at pcppi0 lpt0 at isa0 port 0x378/4 irq 7 wbsio0 at isa0 port 0x2e/2: NCT6776F rev 0x33 lm1 at wbsio0 port 0x290/8: NCT6776F uhub2 at uhub0 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2 uhub3 at uhub1 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2 uhidev0 at uhub3 port 3 configuration 1 interface 0 "Logitech USB-PS/2 Optical Mouse" rev 2.00/13.20 addr 3 uhidev0: iclass 3/1 ums0 at uhidev0: 4 buttons, Z dir wsmouse0 at ums0 mux 0 vscsi0 at root scsibus1 at vscsi0: 256 targets softraid0 at root scsibus2 at softraid0: 256 targets sd0 at scsibus2 targ 1 lun 0: <OPENBSD, SR RAID 1, 005> SCSI2 0/direct fixed sd0: 953869MB, 512 bytes/sector, 1953524640 sectors root on wd0a (f5f9fc374d31f175.a) swap on wd0b dump on wd0b uhub2 detached uhub0 detached wsmouse0 detached ums0 detached uhidev0 detached uhub3 detached uhub1 detached uhub0 at usb0 "Intel EHCI root hub" rev 2.00/1.00 addr 1 uhub1 at usb1 "Intel EHCI root hub" rev 2.00/1.00 addr 1 uhub2 at uhub0 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2 uhub3 at uhub1 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2 uhidev0 at uhub3 port 3 configuration 1 interface 0 "Logitech USB-PS/2 Optical Mouse" rev 2.00/13.20 addr 3 uhidev0: iclass 3/1 ums0 at uhidev0: 4 buttons, Z dir wsmouse0 at ums0 mux 0