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

Reply via email to