I use usbhidaction, a little differently:

- OBSD media server in office, connected to speakers

- Custom microservice on media server, to control volume

- When I am docked at startup (detected in .xsession), configure:

        - Set AUDIODEVICE to office media server for sndio

        - Use usbhidaction to send volume and mute commands to media
          center microservice

This setup works incredibly well - and I would never have considered it
with other OSs.  I would have tried to rig a headphone jack and
splitter or something.  Current config just uses the network.

Since I have other OBSD media servers around the house, I can easily
change the address and send audio & control to other rooms.

Wondering if my custom config will still be possible with ucc...


On 8/18/21 10:24 AM, Florian Obser wrote:
> My microsoft sculpt has a bunch of media keys. I tried mute and
> increment / decrement. They don't seem to have an effect.
>
> --- dmesg.boot        Wed Aug 18 19:19:07 2021
> +++ dmesg.boot.ucc    Wed Aug 18 19:19:16 2021
> @@ -1,7 +1,7 @@
> -OpenBSD 7.0-beta (GENERIC.MP) #131: Wed Aug 18 10:18:06 CEST 2021
> +OpenBSD 7.0-beta (GENERIC.MP) #132: Wed Aug 18 13:41:45 CEST 2021
>      florian@x1:/usr/src/sys/arch/amd64/compile/GENERIC.MP
>  real mem = 8266944512 (7883MB)
> -avail mem = 8000442368 (7629MB)
> +avail mem = 8000446464 (7629MB)
>  random: good seed from bootblocks
>  mpath0 at root
>  scsibus0 at mpath0: 256 targets
> @@ -122,21 +122,21 @@
>  uhidev1 at uhub0 port 2 configuration 1 interface 1 "Microsoft Microsoft\M-. 
> 2.4GHz Transceiver v9.0" rev 2.00/7.97 addr 2
>  uhidev1: iclass 3/1, 26 report ids
>  uhid0 at uhidev1 reportid 18: input=0, output=0, feature=1
> -uhid1 at uhidev1 reportid 23: input=0, output=0, feature=1
> +ucc0 at uhidev1 reportid 23 hid error 6
>  ums0 at uhidev1 reportid 26: 5 buttons, Z and W dir
>  wsmouse2 at ums0 mux 0
>  uhidev2 at uhub0 port 2 configuration 1 interface 2 "Microsoft Microsoft\M-. 
> 2.4GHz Transceiver v9.0" rev 2.00/7.97 addr 2
>  uhidev2: iclass 3/0, 39 report ids
> -uhid2 at uhidev2 reportid 3: input=1, output=0, feature=0
> -uhid3 at uhidev2 reportid 7: input=7, output=0, feature=0
> -uhid4 at uhidev2 reportid 32: input=0, output=0, feature=18
> -uhid5 at uhidev2 reportid 33: input=2, output=0, feature=0
> -uhid6 at uhidev2 reportid 34: input=0, output=0, feature=26
> -uhid7 at uhidev2 reportid 35: input=0, output=0, feature=26
> -uhid8 at uhidev2 reportid 36: input=0, output=0, feature=31
> -uhid9 at uhidev2 reportid 37: input=0, output=0, feature=31
> -uhid10 at uhidev2 reportid 38: input=0, output=0, feature=31
> -uhid11 at uhidev2 reportid 39: input=31, output=0, feature=0
> +uhid1 at uhidev2 reportid 3: input=1, output=0, feature=0
> +ucc1 at uhidev2 reportid 7 keys 1, mappings 0
> +uhid2 at uhidev2 reportid 32: input=0, output=0, feature=18
> +uhid3 at uhidev2 reportid 33: input=2, output=0, feature=0
> +uhid4 at uhidev2 reportid 34: input=0, output=0, feature=26
> +uhid5 at uhidev2 reportid 35: input=0, output=0, feature=26
> +uhid6 at uhidev2 reportid 36: input=0, output=0, feature=31
> +uhid7 at uhidev2 reportid 37: input=0, output=0, feature=31
> +uhid8 at uhidev2 reportid 38: input=0, output=0, feature=31
> +ucc2 at uhidev2 reportid 39 keys 1, mappings 0
>  umb0 at uhub0 port 4 configuration 1 interface 0 "Sierra Wireless Inc. 
> Sierra Wireless EM7345 4G LTE" rev 2.00/17.29 addr 3
>  umodem0 at uhub0 port 4 configuration 1 interface 2 "Sierra Wireless Inc. 
> Sierra Wireless EM7345 4G LTE" rev 2.00/17.29 addr 3
>  umodem0: data interface 3, has no CM over data, has break
> @@ -145,12 +145,12 @@
>  uhub2 at uhub1 port 1 configuration 1 interface 0 "Intel Rate Matching Hub" 
> rev 2.00/0.04 addr 2
>  uhidev3 at uhub2 port 5 configuration 1 interface 0 "ELAN Touchscreen" rev 
> 2.00/0.12 addr 3
>  uhidev3: iclass 3/0, 68 report ids
> -uhid12 at uhidev3 reportid 1: input=115, output=0, feature=0
> -uhid13 at uhidev3 reportid 2: input=64, output=0, feature=0
> -uhid14 at uhidev3 reportid 3: input=0, output=31, feature=0
> -uhid15 at uhidev3 reportid 4: input=19, output=0, feature=0
> -uhid16 at uhidev3 reportid 10: input=0, output=0, feature=1
> -uhid17 at uhidev3 reportid 68: input=0, output=0, feature=255
> +uhid9 at uhidev3 reportid 1: input=115, output=0, feature=0
> +uhid10 at uhidev3 reportid 2: input=64, output=0, feature=0
> +uhid11 at uhidev3 reportid 3: input=0, output=31, feature=0
> +uhid12 at uhidev3 reportid 4: input=19, output=0, feature=0
> +uhid13 at uhidev3 reportid 10: input=0, output=0, feature=1
> +uhid14 at uhidev3 reportid 68: input=0, output=0, feature=255
>  uvideo0 at uhub2 port 8 configuration 1 interface 0 "Chicony Electronics 
> Co.,Ltd. Integrated Camera" rev 2.00/25.09 addr 4
>  video0 at uvideo0
>  vscsi0 at root
>
>
> dmesg.boot.ucc:
> OpenBSD 7.0-beta (GENERIC.MP) #132: Wed Aug 18 13:41:45 CEST 2021
>     florian@x1:/usr/src/sys/arch/amd64/compile/GENERIC.MP
> real mem = 8266944512 (7883MB)
> avail mem = 8000446464 (7629MB)
> random: good seed from bootblocks
> mpath0 at root
> scsibus0 at mpath0: 256 targets
> mainbus0 at root
> bios0 at mainbus0: SMBIOS rev. 2.7 @ 0xdcd3c000 (57 entries)
> bios0: vendor LENOVO version "GRET40WW (1.17 )" date 09/02/2014
> bios0: LENOVO 20A7006VUS
> acpi0 at bios0: ACPI 5.0
> acpi0: sleep states S0 S3 S4 S5
> acpi0: tables DSDT FACP SLIC ASF! DBGP ECDT HPET APIC MCFG SSDT SSDT SSDT 
> SSDT SSDT SSDT UEFI MSDM BATB FPDT UEFI DMAR
> acpi0: wakeup devices LID_(S4) SLPB(S3) IGBE(S4) EXP2(S4) XHCI(S3) EHC1(S3)
> acpitimer0 at acpi0: 3579545 Hz, 24 bits
> acpiec0 at acpi0
> acpihpet0 at acpi0: 14318179 Hz
> acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
> cpu0 at mainbus0: apid 0 (boot processor)
> cpu0: Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz, 1995.71 MHz, 06-45-01
> 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,SMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,SRBDS_CTRL,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
> cpu0: 256KB 64b/line 8-way L2 cache
> cpu0: smt 0, core 0, package 0
> mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges
> cpu0: apic clock running at 99MHz
> cpu0: mwait min=64, max=64, C-substates=0.2.1.2.4.1.1.1, IBE
> cpu1 at mainbus0: apid 1 (application processor)
> cpu1: Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz, 1995.39 MHz, 06-45-01
> cpu1: 
> 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,SMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,SRBDS_CTRL,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
> cpu1: 256KB 64b/line 8-way L2 cache
> cpu1: smt 1, core 0, package 0
> cpu2 at mainbus0: apid 2 (application processor)
> cpu2: Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz, 1995.40 MHz, 06-45-01
> cpu2: 
> 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,SMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,SRBDS_CTRL,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
> cpu2: 256KB 64b/line 8-way L2 cache
> cpu2: smt 0, core 1, package 0
> cpu3 at mainbus0: apid 3 (application processor)
> cpu3: Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz, 1995.39 MHz, 06-45-01
> cpu3: 
> 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,SMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,SRBDS_CTRL,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
> cpu3: 256KB 64b/line 8-way L2 cache
> cpu3: smt 1, core 1, package 0
> ioapic0 at mainbus0: apid 2 pa 0xfec00000, version 20, 40 pins
> acpimcfg0 at acpi0
> acpimcfg0: addr 0xf8000000, bus 0-63
> acpiprt0 at acpi0: bus 0 (PCI0)
> acpiprt1 at acpi0: bus -1 (PEG_)
> acpiprt2 at acpi0: bus 2 (EXP1)
> acpiprt3 at acpi0: bus 3 (EXP2)
> acpiprt4 at acpi0: bus -1 (EXP3)
> dwiic0 at acpi0 I2C1 addr 0xfe105000/0x1000 irq 7
> iic0 at dwiic0
> "CPLM3218" at iic0 addr 0x48 not configured
> acpibtn0 at acpi0: LID_
> acpibtn1 at acpi0: SLPB
> acpipci0 at acpi0 PCI0: 0x00000000 0x00000011 0x00000001
> acpicmos0 at acpi0
> acpibat0 at acpi0: BAT0 model "45N1703" serial  3191 type LiP oem "SMP"
> acpiac0 at acpi0: AC unit online
> acpithinkpad0 at acpi0: version 2.0
> "PNP0C14" at acpi0 not configured
> "PNP0C14" at acpi0 not configured
> "PNP0C14" at acpi0 not configured
> acpicpu0 at acpi0: C3(200@506 mwait.1@0x60), C2(200@148 mwait.1@0x33), 
> C1(1000@1 mwait.1), PSS
> acpicpu1 at acpi0: C3(200@506 mwait.1@0x60), C2(200@148 mwait.1@0x33), 
> C1(1000@1 mwait.1), PSS
> acpicpu2 at acpi0: C3(200@506 mwait.1@0x60), C2(200@148 mwait.1@0x33), 
> C1(1000@1 mwait.1), PSS
> acpicpu3 at acpi0: C3(200@506 mwait.1@0x60), C2(200@148 mwait.1@0x33), 
> C1(1000@1 mwait.1), PSS
> acpipwrres0 at acpi0: PUBS, resource for XHCI, EHC1
> acpitz0 at acpi0: critical temperature is 200 degC
> acpivideo0 at acpi0: VID_
> acpivout0 at acpivideo0: LCD0
> acpivideo1 at acpi0: VID_
> cpu0: using VERW MDS workaround (except on vmm entry)
> cpu0: Enhanced SpeedStep 1995 MHz: speeds: 2701, 2700, 2600, 2400, 2300, 
> 2100, 2000, 1800, 1700, 1600, 1400, 1300, 1100, 1000, 800, 756 MHz
> pci0 at mainbus0 bus 0
> pchb0 at pci0 dev 0 function 0 "Intel Core 4G Host" rev 0x0b
> inteldrm0 at pci0 dev 2 function 0 "Intel HD Graphics" rev 0x0b
> drm0 at inteldrm0
> inteldrm0: msi, HASWELL, gen 7
> azalia0 at pci0 dev 3 function 0 "Intel Core 4G HD Audio" rev 0x0b: msi
> azalia0: No codecs found
> xhci0 at pci0 dev 20 function 0 "Intel 8 Series xHCI" rev 0x04: msi, xHCI 1.0
> usb0 at xhci0: USB revision 3.0
> uhub0 at usb0 configuration 1 interface 0 "Intel xHCI root hub" rev 3.00/1.00 
> addr 1
> em0 at pci0 dev 25 function 0 "Intel I218-LM" rev 0x04: msi, address 
> 54:ee:75:3d:fb:31
> azalia1 at pci0 dev 27 function 0 "Intel 8 Series HD Audio" rev 0x04: msi
> azalia1: codecs: Realtek ALC292
> audio0 at azalia1
> ppb0 at pci0 dev 28 function 0 "Intel 8 Series PCIE" rev 0xe4: msi
> pci1 at ppb0 bus 2
> ppb1 at pci0 dev 28 function 1 "Intel 8 Series PCIE" rev 0xe4: msi
> pci2 at ppb1 bus 3
> iwm0 at pci2 dev 0 function 0 "Intel AC 7260" rev 0x83, msi
> ehci0 at pci0 dev 29 function 0 "Intel 8 Series USB" rev 0x04: apic 2 int 23
> usb1 at ehci0: USB revision 2.0
> uhub1 at usb1 configuration 1 interface 0 "Intel EHCI root hub" rev 2.00/1.00 
> addr 1
> pcib0 at pci0 dev 31 function 0 "Intel 8 Series LPC" rev 0x04
> ahci0 at pci0 dev 31 function 2 "Intel 8 Series AHCI" rev 0x04: msi, AHCI 1.3
> ahci0: port 0: 6.0Gb/s
> scsibus1 at ahci0: 32 targets
> sd0 at scsibus1 targ 0 lun 0: <ATA, TOSHIBA THNSNJ51, JULA> 
> naa.500080dc001bf1e2
> sd0: 488386MB, 512 bytes/sector, 1000215216 sectors, thin
> ichiic0 at pci0 dev 31 function 3 "Intel 8 Series SMBus" rev 0x04: apic 2 int 
> 18
> iic1 at ichiic0
> isa0 at pcib0
> isadma0 at isa0
> pckbc0 at isa0 port 0x60/5 irq 1 irq 12
> pckbd0 at pckbc0 (kbd slot)
> wskbd0 at pckbd0: console keyboard
> pms0 at pckbc0 (aux slot)
> wsmouse0 at pms0 mux 0
> wsmouse1 at pms0 mux 0
> pms0: Synaptics clickpad, firmware 8.1, 0x1e2b1 0x940300 0x2d9240 0xd001a3 
> 0x12e800
> pcppi0 at isa0 port 0x61
> spkr0 at pcppi0
> vmm0 at mainbus0: VMX/EPT
> dt: 445 probes
> uhidev0 at uhub0 port 2 configuration 1 interface 0 "Microsoft Microsoft\M-. 
> 2.4GHz Transceiver v9.0" rev 2.00/7.97 addr 2
> uhidev0: iclass 3/1
> ukbd0 at uhidev0: 8 variable keys, 6 key codes
> wskbd1 at ukbd0 mux 1
> uhidev1 at uhub0 port 2 configuration 1 interface 1 "Microsoft Microsoft\M-. 
> 2.4GHz Transceiver v9.0" rev 2.00/7.97 addr 2
> uhidev1: iclass 3/1, 26 report ids
> uhid0 at uhidev1 reportid 18: input=0, output=0, feature=1
> ucc0 at uhidev1 reportid 23 hid error 6
> ums0 at uhidev1 reportid 26: 5 buttons, Z and W dir
> wsmouse2 at ums0 mux 0
> uhidev2 at uhub0 port 2 configuration 1 interface 2 "Microsoft Microsoft\M-. 
> 2.4GHz Transceiver v9.0" rev 2.00/7.97 addr 2
> uhidev2: iclass 3/0, 39 report ids
> uhid1 at uhidev2 reportid 3: input=1, output=0, feature=0
> ucc1 at uhidev2 reportid 7 keys 1, mappings 0
> uhid2 at uhidev2 reportid 32: input=0, output=0, feature=18
> uhid3 at uhidev2 reportid 33: input=2, output=0, feature=0
> uhid4 at uhidev2 reportid 34: input=0, output=0, feature=26
> uhid5 at uhidev2 reportid 35: input=0, output=0, feature=26
> uhid6 at uhidev2 reportid 36: input=0, output=0, feature=31
> uhid7 at uhidev2 reportid 37: input=0, output=0, feature=31
> uhid8 at uhidev2 reportid 38: input=0, output=0, feature=31
> ucc2 at uhidev2 reportid 39 keys 1, mappings 0
> umb0 at uhub0 port 4 configuration 1 interface 0 "Sierra Wireless Inc. Sierra 
> Wireless EM7345 4G LTE" rev 2.00/17.29 addr 3
> umodem0 at uhub0 port 4 configuration 1 interface 2 "Sierra Wireless Inc. 
> Sierra Wireless EM7345 4G LTE" rev 2.00/17.29 addr 3
> umodem0: data interface 3, has no CM over data, has break
> umodem0: status change notification available
> ucom0 at umodem0
> uhub2 at uhub1 port 1 configuration 1 interface 0 "Intel Rate Matching Hub" 
> rev 2.00/0.04 addr 2
> uhidev3 at uhub2 port 5 configuration 1 interface 0 "ELAN Touchscreen" rev 
> 2.00/0.12 addr 3
> uhidev3: iclass 3/0, 68 report ids
> uhid9 at uhidev3 reportid 1: input=115, output=0, feature=0
> uhid10 at uhidev3 reportid 2: input=64, output=0, feature=0
> uhid11 at uhidev3 reportid 3: input=0, output=31, feature=0
> uhid12 at uhidev3 reportid 4: input=19, output=0, feature=0
> uhid13 at uhidev3 reportid 10: input=0, output=0, feature=1
> uhid14 at uhidev3 reportid 68: input=0, output=0, feature=255
> uvideo0 at uhub2 port 8 configuration 1 interface 0 "Chicony Electronics 
> Co.,Ltd. Integrated Camera" rev 2.00/25.09 addr 4
> video0 at uvideo0
> vscsi0 at root
> scsibus2 at vscsi0: 256 targets
> softraid0 at root
> scsibus3 at softraid0: 256 targets
> sd1 at scsibus3 targ 1 lun 0: <OPENBSD, SR CRYPTO, 006>
> sd1: 488381MB, 512 bytes/sector, 1000206308 sectors
> root on sd1a (f3054894d8af4b99.a) swap on sd1b dump on sd1b
> inteldrm0: 2560x1440, 32bpp
> wsdisplay0 at inteldrm0 mux 1: console (std, vt100 emulation), using wskbd0
> wskbd1: connecting to wsdisplay0
> wsdisplay0: screen 1-5 added (std, vt100 emulation)
> iwm0: hw rev 0x140, fw ver 17.3216344376.0, address 5c:c5:d4:63:b3:d9
>
> dmesg.boot:
> OpenBSD 7.0-beta (GENERIC.MP) #131: Wed Aug 18 10:18:06 CEST 2021
>     florian@x1:/usr/src/sys/arch/amd64/compile/GENERIC.MP
> real mem = 8266944512 (7883MB)
> avail mem = 8000442368 (7629MB)
> random: good seed from bootblocks
> mpath0 at root
> scsibus0 at mpath0: 256 targets
> mainbus0 at root
> bios0 at mainbus0: SMBIOS rev. 2.7 @ 0xdcd3c000 (57 entries)
> bios0: vendor LENOVO version "GRET40WW (1.17 )" date 09/02/2014
> bios0: LENOVO 20A7006VUS
> acpi0 at bios0: ACPI 5.0
> acpi0: sleep states S0 S3 S4 S5
> acpi0: tables DSDT FACP SLIC ASF! DBGP ECDT HPET APIC MCFG SSDT SSDT SSDT 
> SSDT SSDT SSDT UEFI MSDM BATB FPDT UEFI DMAR
> acpi0: wakeup devices LID_(S4) SLPB(S3) IGBE(S4) EXP2(S4) XHCI(S3) EHC1(S3)
> acpitimer0 at acpi0: 3579545 Hz, 24 bits
> acpiec0 at acpi0
> acpihpet0 at acpi0: 14318179 Hz
> acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
> cpu0 at mainbus0: apid 0 (boot processor)
> cpu0: Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz, 1995.71 MHz, 06-45-01
> 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,SMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,SRBDS_CTRL,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
> cpu0: 256KB 64b/line 8-way L2 cache
> cpu0: smt 0, core 0, package 0
> mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges
> cpu0: apic clock running at 99MHz
> cpu0: mwait min=64, max=64, C-substates=0.2.1.2.4.1.1.1, IBE
> cpu1 at mainbus0: apid 1 (application processor)
> cpu1: Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz, 1995.39 MHz, 06-45-01
> cpu1: 
> 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,SMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,SRBDS_CTRL,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
> cpu1: 256KB 64b/line 8-way L2 cache
> cpu1: smt 1, core 0, package 0
> cpu2 at mainbus0: apid 2 (application processor)
> cpu2: Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz, 1995.40 MHz, 06-45-01
> cpu2: 
> 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,SMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,SRBDS_CTRL,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
> cpu2: 256KB 64b/line 8-way L2 cache
> cpu2: smt 0, core 1, package 0
> cpu3 at mainbus0: apid 3 (application processor)
> cpu3: Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz, 1995.39 MHz, 06-45-01
> cpu3: 
> 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,SMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,SRBDS_CTRL,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
> cpu3: 256KB 64b/line 8-way L2 cache
> cpu3: smt 1, core 1, package 0
> ioapic0 at mainbus0: apid 2 pa 0xfec00000, version 20, 40 pins
> acpimcfg0 at acpi0
> acpimcfg0: addr 0xf8000000, bus 0-63
> acpiprt0 at acpi0: bus 0 (PCI0)
> acpiprt1 at acpi0: bus -1 (PEG_)
> acpiprt2 at acpi0: bus 2 (EXP1)
> acpiprt3 at acpi0: bus 3 (EXP2)
> acpiprt4 at acpi0: bus -1 (EXP3)
> dwiic0 at acpi0 I2C1 addr 0xfe105000/0x1000 irq 7
> iic0 at dwiic0
> "CPLM3218" at iic0 addr 0x48 not configured
> acpibtn0 at acpi0: LID_
> acpibtn1 at acpi0: SLPB
> acpipci0 at acpi0 PCI0: 0x00000000 0x00000011 0x00000001
> acpicmos0 at acpi0
> acpibat0 at acpi0: BAT0 model "45N1703" serial  3191 type LiP oem "SMP"
> acpiac0 at acpi0: AC unit online
> acpithinkpad0 at acpi0: version 2.0
> "PNP0C14" at acpi0 not configured
> "PNP0C14" at acpi0 not configured
> "PNP0C14" at acpi0 not configured
> acpicpu0 at acpi0: C3(200@506 mwait.1@0x60), C2(200@148 mwait.1@0x33), 
> C1(1000@1 mwait.1), PSS
> acpicpu1 at acpi0: C3(200@506 mwait.1@0x60), C2(200@148 mwait.1@0x33), 
> C1(1000@1 mwait.1), PSS
> acpicpu2 at acpi0: C3(200@506 mwait.1@0x60), C2(200@148 mwait.1@0x33), 
> C1(1000@1 mwait.1), PSS
> acpicpu3 at acpi0: C3(200@506 mwait.1@0x60), C2(200@148 mwait.1@0x33), 
> C1(1000@1 mwait.1), PSS
> acpipwrres0 at acpi0: PUBS, resource for XHCI, EHC1
> acpitz0 at acpi0: critical temperature is 200 degC
> acpivideo0 at acpi0: VID_
> acpivout0 at acpivideo0: LCD0
> acpivideo1 at acpi0: VID_
> cpu0: using VERW MDS workaround (except on vmm entry)
> cpu0: Enhanced SpeedStep 1995 MHz: speeds: 2701, 2700, 2600, 2400, 2300, 
> 2100, 2000, 1800, 1700, 1600, 1400, 1300, 1100, 1000, 800, 756 MHz
> pci0 at mainbus0 bus 0
> pchb0 at pci0 dev 0 function 0 "Intel Core 4G Host" rev 0x0b
> inteldrm0 at pci0 dev 2 function 0 "Intel HD Graphics" rev 0x0b
> drm0 at inteldrm0
> inteldrm0: msi, HASWELL, gen 7
> azalia0 at pci0 dev 3 function 0 "Intel Core 4G HD Audio" rev 0x0b: msi
> azalia0: No codecs found
> xhci0 at pci0 dev 20 function 0 "Intel 8 Series xHCI" rev 0x04: msi, xHCI 1.0
> usb0 at xhci0: USB revision 3.0
> uhub0 at usb0 configuration 1 interface 0 "Intel xHCI root hub" rev 3.00/1.00 
> addr 1
> em0 at pci0 dev 25 function 0 "Intel I218-LM" rev 0x04: msi, address 
> 54:ee:75:3d:fb:31
> azalia1 at pci0 dev 27 function 0 "Intel 8 Series HD Audio" rev 0x04: msi
> azalia1: codecs: Realtek ALC292
> audio0 at azalia1
> ppb0 at pci0 dev 28 function 0 "Intel 8 Series PCIE" rev 0xe4: msi
> pci1 at ppb0 bus 2
> ppb1 at pci0 dev 28 function 1 "Intel 8 Series PCIE" rev 0xe4: msi
> pci2 at ppb1 bus 3
> iwm0 at pci2 dev 0 function 0 "Intel AC 7260" rev 0x83, msi
> ehci0 at pci0 dev 29 function 0 "Intel 8 Series USB" rev 0x04: apic 2 int 23
> usb1 at ehci0: USB revision 2.0
> uhub1 at usb1 configuration 1 interface 0 "Intel EHCI root hub" rev 2.00/1.00 
> addr 1
> pcib0 at pci0 dev 31 function 0 "Intel 8 Series LPC" rev 0x04
> ahci0 at pci0 dev 31 function 2 "Intel 8 Series AHCI" rev 0x04: msi, AHCI 1.3
> ahci0: port 0: 6.0Gb/s
> scsibus1 at ahci0: 32 targets
> sd0 at scsibus1 targ 0 lun 0: <ATA, TOSHIBA THNSNJ51, JULA> 
> naa.500080dc001bf1e2
> sd0: 488386MB, 512 bytes/sector, 1000215216 sectors, thin
> ichiic0 at pci0 dev 31 function 3 "Intel 8 Series SMBus" rev 0x04: apic 2 int 
> 18
> iic1 at ichiic0
> isa0 at pcib0
> isadma0 at isa0
> pckbc0 at isa0 port 0x60/5 irq 1 irq 12
> pckbd0 at pckbc0 (kbd slot)
> wskbd0 at pckbd0: console keyboard
> pms0 at pckbc0 (aux slot)
> wsmouse0 at pms0 mux 0
> wsmouse1 at pms0 mux 0
> pms0: Synaptics clickpad, firmware 8.1, 0x1e2b1 0x940300 0x2d9240 0xd001a3 
> 0x12e800
> pcppi0 at isa0 port 0x61
> spkr0 at pcppi0
> vmm0 at mainbus0: VMX/EPT
> dt: 445 probes
> uhidev0 at uhub0 port 2 configuration 1 interface 0 "Microsoft Microsoft\M-. 
> 2.4GHz Transceiver v9.0" rev 2.00/7.97 addr 2
> uhidev0: iclass 3/1
> ukbd0 at uhidev0: 8 variable keys, 6 key codes
> wskbd1 at ukbd0 mux 1
> uhidev1 at uhub0 port 2 configuration 1 interface 1 "Microsoft Microsoft\M-. 
> 2.4GHz Transceiver v9.0" rev 2.00/7.97 addr 2
> uhidev1: iclass 3/1, 26 report ids
> uhid0 at uhidev1 reportid 18: input=0, output=0, feature=1
> uhid1 at uhidev1 reportid 23: input=0, output=0, feature=1
> ums0 at uhidev1 reportid 26: 5 buttons, Z and W dir
> wsmouse2 at ums0 mux 0
> uhidev2 at uhub0 port 2 configuration 1 interface 2 "Microsoft Microsoft\M-. 
> 2.4GHz Transceiver v9.0" rev 2.00/7.97 addr 2
> uhidev2: iclass 3/0, 39 report ids
> uhid2 at uhidev2 reportid 3: input=1, output=0, feature=0
> uhid3 at uhidev2 reportid 7: input=7, output=0, feature=0
> uhid4 at uhidev2 reportid 32: input=0, output=0, feature=18
> uhid5 at uhidev2 reportid 33: input=2, output=0, feature=0
> uhid6 at uhidev2 reportid 34: input=0, output=0, feature=26
> uhid7 at uhidev2 reportid 35: input=0, output=0, feature=26
> uhid8 at uhidev2 reportid 36: input=0, output=0, feature=31
> uhid9 at uhidev2 reportid 37: input=0, output=0, feature=31
> uhid10 at uhidev2 reportid 38: input=0, output=0, feature=31
> uhid11 at uhidev2 reportid 39: input=31, output=0, feature=0
> umb0 at uhub0 port 4 configuration 1 interface 0 "Sierra Wireless Inc. Sierra 
> Wireless EM7345 4G LTE" rev 2.00/17.29 addr 3
> umodem0 at uhub0 port 4 configuration 1 interface 2 "Sierra Wireless Inc. 
> Sierra Wireless EM7345 4G LTE" rev 2.00/17.29 addr 3
> umodem0: data interface 3, has no CM over data, has break
> umodem0: status change notification available
> ucom0 at umodem0
> uhub2 at uhub1 port 1 configuration 1 interface 0 "Intel Rate Matching Hub" 
> rev 2.00/0.04 addr 2
> uhidev3 at uhub2 port 5 configuration 1 interface 0 "ELAN Touchscreen" rev 
> 2.00/0.12 addr 3
> uhidev3: iclass 3/0, 68 report ids
> uhid12 at uhidev3 reportid 1: input=115, output=0, feature=0
> uhid13 at uhidev3 reportid 2: input=64, output=0, feature=0
> uhid14 at uhidev3 reportid 3: input=0, output=31, feature=0
> uhid15 at uhidev3 reportid 4: input=19, output=0, feature=0
> uhid16 at uhidev3 reportid 10: input=0, output=0, feature=1
> uhid17 at uhidev3 reportid 68: input=0, output=0, feature=255
> uvideo0 at uhub2 port 8 configuration 1 interface 0 "Chicony Electronics 
> Co.,Ltd. Integrated Camera" rev 2.00/25.09 addr 4
> video0 at uvideo0
> vscsi0 at root
> scsibus2 at vscsi0: 256 targets
> softraid0 at root
> scsibus3 at softraid0: 256 targets
> sd1 at scsibus3 targ 1 lun 0: <OPENBSD, SR CRYPTO, 006>
> sd1: 488381MB, 512 bytes/sector, 1000206308 sectors
> root on sd1a (f3054894d8af4b99.a) swap on sd1b dump on sd1b
> inteldrm0: 2560x1440, 32bpp
> wsdisplay0 at inteldrm0 mux 1: console (std, vt100 emulation), using wskbd0
> wskbd1: connecting to wsdisplay0
> wsdisplay0: screen 1-5 added (std, vt100 emulation)
> iwm0: hw rev 0x140, fw ver 17.3216344376.0, address 5c:c5:d4:63:b3:d9
>
> and the raw dumps:
> uhid0:
> 0x05 0x01 0x09 0x02 0xa1 0x01 0x05 0x01 0x09 0x02 0xa1 0x02 0x85 0x1a 0x09 
> 0x01 0xa1 0x00 0x05 0x09 0x19 0x01 0x29 0x05 0x95 0x05 0x75 0x01 0x15 0x00 
> 0x25 0x01 0x81 0x02 0x75 0x03 0x95 0x01 0x81 0x01 0x05 0x01 0x09 0x30 0x09 
> 0x31 0x95 0x02 0x75 0x10 0x16 0x01 0x80 0x26 0xff 0x7f 0x81 0x06 0xa1 0x02 
> 0x85 0x12 0x09 0x48 0x95 0x01 0x75 0x02 0x15 0x00 0x25 0x01 0x35 0x01 0x45 
> 0x0c 0xb1 0x02 0x85 0x1a 0x09 0x38 0x35 0x00 0x45 0x00 0x95 0x01 0x75 0x10 
> 0x16 0x01 0x80 0x26 0xff 0x7f 0x81 0x06 0xc0 0xa1 0x02 0x85 0x12 0x09 0x48 
> 0x75 0x02 0x15 0x00 0x25 0x01 0x35 0x01 0x45 0x0c 0xb1 0x02 0x35 0x00 0x45 
> 0x00 0x75 0x04 0xb1 0x01 0x85 0x1a 0x05 0x0c 0x95 0x01 0x75 0x10 0x16 0x01 
> 0x80 0x26 0xff 0x7f 0x0a 0x38 0x02 0x81 0x06 0xc0 0xc0 0xc0 0xc0 0x05 0x0c 
> 0x09 0x01 0xa1 0x01 0x05 0x01 0x09 0x02 0xa1 0x02 0x85 0x1f 0x05 0x0c 0x0a 
> 0x38 0x02 0x95 0x01 0x75 0x10 0x16 0x01 0x80 0x26 0xff 0x7f 0x81 0x06 0x85 
> 0x17 0x06 0x00 0xff 0x0a 0x06 0xff 0x0a 0x0f 0xff 0x15 0x00 0x25 0x01 0x35 
> 0x01 0x45 0x0c 0x95 0x02 0x75 0x02 0xb1 0x02 0x0a 0x04 0xff 0x35 0x00 0x45 
> 0x00 0x95 0x01 0x75 0x01 0xb1 0x02 0x75 0x03 0xb1 0x01 0xc0 0xc0
>
> uhid1:
> 0x05 0x01 0x09 0x02 0xa1 0x01 0x05 0x01 0x09 0x02 0xa1 0x02 0x85 0x1a 0x09 
> 0x01 0xa1 0x00 0x05 0x09 0x19 0x01 0x29 0x05 0x95 0x05 0x75 0x01 0x15 0x00 
> 0x25 0x01 0x81 0x02 0x75 0x03 0x95 0x01 0x81 0x01 0x05 0x01 0x09 0x30 0x09 
> 0x31 0x95 0x02 0x75 0x10 0x16 0x01 0x80 0x26 0xff 0x7f 0x81 0x06 0xa1 0x02 
> 0x85 0x12 0x09 0x48 0x95 0x01 0x75 0x02 0x15 0x00 0x25 0x01 0x35 0x01 0x45 
> 0x0c 0xb1 0x02 0x85 0x1a 0x09 0x38 0x35 0x00 0x45 0x00 0x95 0x01 0x75 0x10 
> 0x16 0x01 0x80 0x26 0xff 0x7f 0x81 0x06 0xc0 0xa1 0x02 0x85 0x12 0x09 0x48 
> 0x75 0x02 0x15 0x00 0x25 0x01 0x35 0x01 0x45 0x0c 0xb1 0x02 0x35 0x00 0x45 
> 0x00 0x75 0x04 0xb1 0x01 0x85 0x1a 0x05 0x0c 0x95 0x01 0x75 0x10 0x16 0x01 
> 0x80 0x26 0xff 0x7f 0x0a 0x38 0x02 0x81 0x06 0xc0 0xc0 0xc0 0xc0 0x05 0x0c 
> 0x09 0x01 0xa1 0x01 0x05 0x01 0x09 0x02 0xa1 0x02 0x85 0x1f 0x05 0x0c 0x0a 
> 0x38 0x02 0x95 0x01 0x75 0x10 0x16 0x01 0x80 0x26 0xff 0x7f 0x81 0x06 0x85 
> 0x17 0x06 0x00 0xff 0x0a 0x06 0xff 0x0a 0x0f 0xff 0x15 0x00 0x25 0x01 0x35 
> 0x01 0x45 0x0c 0x95 0x02 0x75 0x02 0xb1 0x02 0x0a 0x04 0xff 0x35 0x00 0x45 
> 0x00 0x95 0x01 0x75 0x01 0xb1 0x02 0x75 0x03 0xb1 0x01 0xc0 0xc0
>
> uhid2:
> 0x05 0x0c 0x09 0x01 0xa1 0x01 0x85 0x20 0x06 0x00 0xff 0x15 0x00 0x26 0xff 
> 0x00 0x75 0x08 0x95 0x12 0x0a 0x0a 0xfa 0xb1 0x02 0x85 0x21 0x06 0x00 0xff 
> 0x15 0x00 0x25 0x01 0x75 0x01 0x95 0x10 0x1a 0x10 0xfa 0x2a 0x1f 0xfa 0x81 
> 0x02 0x85 0x28 0x06 0x00 0xff 0x75 0x01 0x95 0x18 0x1a 0x10 0xfa 0x2a 0x1f 
> 0xfa 0xb1 0x02 0x85 0x22 0x06 0x00 0xff 0x15 0x00 0x26 0xff 0x00 0x75 0x08 
> 0x95 0x1a 0x0a 0x0a 0xfa 0xb1 0x02 0x85 0x23 0x06 0x00 0xff 0x0a 0x0a 0xfa 
> 0xb1 0x02 0x85 0xa2 0x06 0x00 0xff 0x0a 0x0a 0xfa 0xb1 0x02 0x85 0xa3 0x06 
> 0x00 0xff 0x0a 0x0a 0xfa 0xb1 0x02 0x85 0x24 0x06 0x00 0xff 0x95 0x1f 0x0a 
> 0x0a 0xfa 0xb1 0x02 0x85 0x25 0x06 0x00 0xff 0x0a 0x0a 0xfa 0xb1 0x02 0x85 
> 0xa4 0x06 0x00 0xff 0x95 0x1f 0x0a 0x0a 0xfa 0xb1 0x02 0x85 0xa5 0x06 0x00 
> 0xff 0x0a 0x0a 0xfa 0xb1 0x02 0x85 0x26 0x06 0x00 0xff 0x0a 0x0a 0xfa 0xb1 
> 0x02 0x85 0x27 0x06 0x00 0xff 0x0a 0x0a 0xfa 0x81 0x02 0xc0 0x05 0x0c 0x09 
> 0x01 0xa1 0x01 0x85 0x07 0x05 0x0c 0x19 0x00 0x2a 0xff 0x03 0x95 0x01 0x75 
> 0x10 0x15 0x00 0x26 0xff 0x03 0x81 0x00 0x05 0x07 0x19 0x00 0x29 0xff 0x75 
> 0x08 0x26 0xff 0x00 0x81 0x00 0x81 0x01 0x06 0x00 0xff 0x0a 0x03 0xfe 0x0a 
> 0x04 0xfe 0x75 0x01 0x95 0x02 0x25 0x01 0x81 0x02 0x0a 0x05 0xff 0x95 0x01 
> 0x75 0x05 0x25 0x1f 0x81 0x02 0x75 0x01 0x81 0x01 0x1a 0x01 0xfd 0x2a 0xff 
> 0xfd 0x15 0x01 0x26 0xff 0x00 0x75 0x08 0x81 0x00 0x0a 0x02 0xff 0x26 0xff 
> 0x00 0x15 0x00 0x81 0x02 0xc0 0x05 0x01 0x09 0x80 0xa1 0x01 0x85 0x03 0x19 
> 0x00 0x29 0xff 0x15 0x00 0x26 0xff 0x00 0x81 0x00 0xc0
>
>
> On 2021-08-17 20:13 +02, Anton Lindqvist <an...@openbsd.org> wrote:
>> Hi,
>> Here's a new driver for USB HID Consumer Control keyboards. Such
>> keyboard is a pseudo device which is used to expose audio and
>> application launch keys. My prime motivation is to get the volume mute,
>> increment and decrement keys to just work on my keyboard without the
>> need to use usbhidaction(1).
>>
>> ucc(4) attaches a wskbd(4) keyboard "on top" making it appear like an
>> ordinary keyboard, which also makes it possible to inject key
>> press/release input. It supports both translating and raw mode making it
>> compatible with the ordinary console and X11.
>>
>> My keyboard for instance exposes 42 keys in its input report. I only
>> care about the volume and audio related ones and therefore only added
>> mappings for those. Additional mappings should be trivial to add if
>> desired.
>>
>> Testing would be much appreciated.
>>
>> Comments? OK?
>>
>> diff --git share/man/man4/Makefile share/man/man4/Makefile
>> index 6a0ecb20653..63b33660159 100644
>> --- share/man/man4/Makefile
>> +++ share/man/man4/Makefile
>> @@ -84,7 +84,7 @@ MAN=       aac.4 abcrtc.4 abl.4 ac97.4 acphy.4 acrtc.4 \
>>      tlphy.4 thmc.4 tpm.4 tpmr.4 tqphy.4 trm.4 trunk.4 tsl.4 tty.4 \
>>      tun.4 tap.4 twe.4 \
>>      txp.4 txphy.4 uaudio.4 uark.4 uath.4 ubcmtp.4 uberry.4 ubsa.4 \
>> -    ubsec.4 ucom.4 uchcom.4 ucrcom.4 ucycom.4 ukspan.4 uslhcom.4 \
>> +    ubsec.4 ucc.4 ucom.4 uchcom.4 ucrcom.4 ucycom.4 ukspan.4 uslhcom.4 \
>>      udav.4 udcf.4 udl.4 udp.4 udsbr.4 \
>>      uftdi.4 ugen.4 ugl.4 ugold.4 uguru.4 uhci.4 uhid.4 uhidev.4 uhidpp.4 \
>>      uipaq.4 ujoy.4 uk.4 ukbd.4 \
>> diff --git share/man/man4/ucc.4 share/man/man4/ucc.4
>> new file mode 100644
>> index 00000000000..413c88aa6af
>> --- /dev/null
>> +++ share/man/man4/ucc.4
>> @@ -0,0 +1,45 @@
>> +.\" $OpenBSD$
>> +.\"
>> +.\" Copyright (c) 2021 Anton Lindqvist <an...@openbsd.org>
>> +.\"
>> +.\" Permission to use, copy, modify, and distribute this software for any
>> +.\" purpose with or without fee is hereby granted, provided that the above
>> +.\" copyright notice and this permission notice appear in all copies.
>> +.\"
>> +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
>> +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
>> +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
>> +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
>> +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>> +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> +.\"
>> +.Dd $Mdocdate$
>> +.Dt UCC 4
>> +.Os
>> +.Sh NAME
>> +.Nm ucc
>> +.Nd Consumer Control keyboards
>> +.Sh SYNOPSIS
>> +.Cd "ucc* at uhidev?"
>> +.Cd "wsbkd* at ucc? mux 1"
>> +.Sh DESCRIPTION
>> +The
>> +.Nm
>> +driver provides support for Consumer Control pseudo keyboards, often used to
>> +expose audio and application launch keys.
>> +.Sh SEE ALSO
>> +.Xr intro 4 ,
>> +.Xr uhidev 4 ,
>> +.Xr usb 4 ,
>> +.Xr wskbd 4
>> +.Sh HISTORY
>> +The
>> +.Nm
>> +driver first appeared in
>> +.Ox 7.0 .
>> +.Sh AUTHORS
>> +The
>> +.Nm
>> +driver was written by
>> +.An Anton Lindqvist Aq Mt an...@openbsd.org .
>> diff --git share/man/man4/uhidev.4 share/man/man4/uhidev.4
>> index 02252789a3f..d398c564bd5 100644
>> --- share/man/man4/uhidev.4
>> +++ share/man/man4/uhidev.4
>> @@ -37,6 +37,7 @@
>>  .Sh SYNOPSIS
>>  .Cd "uhidev*  at uhub?"
>>  .Cd "fido*    at uhidev?"
>> +.Cd "ucc*     at uhidev?"
>>  .Cd "ucycom*  at uhidev?"
>>  .Cd "ugold*   at uhidev?"
>>  .Cd "uhid*    at uhidev?"
>> @@ -72,6 +73,7 @@ only dispatches data to them based on the report id.
>>  .Sh SEE ALSO
>>  .Xr fido 4 ,
>>  .Xr intro 4 ,
>> +.Xr ucc 4 ,
>>  .Xr ucycom 4 ,
>>  .Xr ugold 4 ,
>>  .Xr uhid 4 ,
>> diff --git share/man/man4/usb.4 share/man/man4/usb.4
>> index dad3d3a97d9..d159d8b27f3 100644
>> --- share/man/man4/usb.4
>> +++ share/man/man4/usb.4
>> @@ -249,6 +249,8 @@ D-Link DSB-R100 USB radio device
>>  FIDO/U2F security keys
>>  .It Xr ubcmtp 4
>>  Broadcom trackpad mouse
>> +.It Xr ucc 4
>> +USB Consumer Control keyboards
>>  .It Xr ugold 4
>>  TEMPer gold HID thermometer and hygrometer
>>  .It Xr uhid 4
>> diff --git sys/arch/alpha/conf/GENERIC sys/arch/alpha/conf/GENERIC
>> index 8af652ce301..54d4a45cd4e 100644
>> --- sys/arch/alpha/conf/GENERIC
>> +++ sys/arch/alpha/conf/GENERIC
>> @@ -107,6 +107,8 @@ uslhcom* at uhidev?                      # Silicon Labs 
>> CP2110 USB HID UART
>>  ucom*       at uslhcom?
>>  uhid*       at uhidev?                      # USB generic HID support
>>  fido*       at uhidev?                      # FIDO/U2F security key support
>> +ucc*        at uhidev?                      # Consumer Control keyboards
>> +wskbd*      at ucc? mux 1
>>  ujoy*       at uhidev?                      # USB joystick/gamecontroller 
>> support
>>  uhidpp*     at uhidev?              # Logitech HID++ Devices
>>  upd*        at uhidev?                      # USB Power Devices sensors
>> diff --git sys/arch/amd64/conf/GENERIC sys/arch/amd64/conf/GENERIC
>> index c0c16f7c986..0d278739ccf 100644
>> --- sys/arch/amd64/conf/GENERIC
>> +++ sys/arch/amd64/conf/GENERIC
>> @@ -286,6 +286,8 @@ uslhcom* at uhidev?              # Silicon Labs CP2110 
>> USB HID UART
>>  ucom*       at uslhcom?
>>  uhid*       at uhidev?              # USB generic HID support
>>  fido*       at uhidev?              # FIDO/U2F security key support
>> +ucc*        at uhidev?              # Consumer Control keyboards
>> +wskbd*      at ucc? mux 1
>>  ujoy*       at uhidev?              # USB joystick/gamecontroller support
>>  uhidpp*     at uhidev?              # Logitech HID++ Devices
>>  upd*        at uhidev?              # USB Power Devices sensors
>> diff --git sys/arch/arm64/conf/GENERIC sys/arch/arm64/conf/GENERIC
>> index ff54bee0a9a..0cb8f4edb05 100644
>> --- sys/arch/arm64/conf/GENERIC
>> +++ sys/arch/arm64/conf/GENERIC
>> @@ -392,6 +392,8 @@ uslhcom* at uhidev?              # Silicon Labs CP2110 
>> USB HID UART
>>  ucom*               at uslhcom?
>>  uhid*               at uhidev?              # USB generic HID support
>>  fido*               at uhidev?              # FIDO/U2F security key support
>> +ucc*                at uhidev?              # Consumer Control keyboards
>> +wskbd*              at ucc? mux 1
>>  ujoy*               at uhidev?              # USB joystick/gamecontroller 
>> support
>>  uhidpp*             at uhidev?              # Logitech HID++ Devices
>>  upd*                at uhidev?              # USB Power Devices sensors
>> diff --git sys/arch/armv7/conf/GENERIC sys/arch/armv7/conf/GENERIC
>> index 1af5eb8dd85..271177bf2ab 100644
>> --- sys/arch/armv7/conf/GENERIC
>> +++ sys/arch/armv7/conf/GENERIC
>> @@ -327,6 +327,8 @@ uslhcom* at uhidev?              # Silicon Labs CP2110 
>> USB HID UART
>>  ucom*       at uslhcom?
>>  uhid*       at uhidev?              # USB generic HID support
>>  fido*       at uhidev?              # FIDO/U2F security key support
>> +ucc*        at uhidev?              # Consumer Control keyboards
>> +wskbd*      at ucc? mux 1
>>  ujoy*       at uhidev?              # USB joystick/gamecontroller support
>>  uhidpp*     at uhidev?              # Logitech HID++ Devices
>>  upd*        at uhidev?              # USB Power Devices sensors
>> diff --git sys/arch/hppa/conf/GENERIC sys/arch/hppa/conf/GENERIC
>> index 1a27dbb18c0..91e0888af4c 100644
>> --- sys/arch/hppa/conf/GENERIC
>> +++ sys/arch/hppa/conf/GENERIC
>> @@ -111,6 +111,8 @@ ukbd*    at uhidev?              # USB keyboard
>>  wskbd*      at ukbd? mux 1
>>  uhid*       at uhidev?              # USB generic HID support
>>  fido*       at uhidev?              # FIDO/U2F security key support
>> +ucc*        at uhidev?              # Consumer Control keyboards
>> +wskbd*      at ucc? mux 1
>>  ujoy*       at uhidev?              # USB joystick/gamecontroller support
>>  uhidpp*     at uhidev?              # Logitech HID++ Devices
>>  upd*        at uhidev?              # USB Power Devices sensors
>> diff --git sys/arch/i386/conf/GENERIC sys/arch/i386/conf/GENERIC
>> index b49353a92d0..7e3144dba53 100644
>> --- sys/arch/i386/conf/GENERIC
>> +++ sys/arch/i386/conf/GENERIC
>> @@ -284,6 +284,8 @@ uticom* at uhub?         # TI serial
>>  ucom*       at uticom?
>>  uhid*       at uhidev?              # USB generic HID support
>>  fido*       at uhidev?              # FIDO/U2F security key support
>> +ucc*        at uhidev?              # Consumer Control keyboards
>> +wskbd*      at ucc? mux 1
>>  ujoy*       at uhidev?              # USB joystick/gamecontroller support
>>  uhidpp*     at uhidev?              # Logitech HID++ Devices
>>  upd*        at uhidev?              # USB Power Devices sensors
>> diff --git sys/arch/landisk/conf/GENERIC sys/arch/landisk/conf/GENERIC
>> index a2091413514..133218afe22 100644
>> --- sys/arch/landisk/conf/GENERIC
>> +++ sys/arch/landisk/conf/GENERIC
>> @@ -137,6 +137,8 @@ uslhcom* at uhidev?              # Silicon Labs CP2110 
>> USB HID UART
>>  ucom*       at uslhcom?
>>  uhid*       at uhidev?              # USB generic HID support
>>  fido*       at uhidev?              # FIDO/U2F security key support
>> +ucc*        at uhidev?              # Consumer Control keyboards
>> +wskbd*      at ucc? mux 1
>>  ujoy*       at uhidev?              # USB joystick/gamecontroller support
>>  uhidpp*     at uhidev?              # Logitech HID++ Devices
>>  upd*        at uhidev?              # USB Power Devices sensors
>> diff --git sys/arch/loongson/conf/GENERIC sys/arch/loongson/conf/GENERIC
>> index d213bd976f9..f3ab1b34cf1 100644
>> --- sys/arch/loongson/conf/GENERIC
>> +++ sys/arch/loongson/conf/GENERIC
>> @@ -164,6 +164,8 @@ uslhcom*         at uhidev?      # Silicon Labs CP2110 
>> USB HID UART
>>  ucom*               at uslhcom?
>>  uhid*               at uhidev?      # USB generic HID support
>>  fido*               at uhidev?      # FIDO/U2F security key support
>> +ucc*                at uhidev?      # Consumer Control keyboards
>> +wskbd*              at ucc? mux 1
>>  ujoy*               at uhidev?      # USB joystick/gamecontroller support
>>  uhidpp*             at uhidev?      # Logitech HID++ Devices
>>  upd*                at uhidev?      # USB Power Devices sensors
>> diff --git sys/arch/macppc/conf/GENERIC sys/arch/macppc/conf/GENERIC
>> index 34014204a23..872e74601a2 100644
>> --- sys/arch/macppc/conf/GENERIC
>> +++ sys/arch/macppc/conf/GENERIC
>> @@ -260,6 +260,8 @@ uslhcom* at uhidev?              # Silicon Labs CP2110 
>> USB HID UART
>>  ucom*       at uslhcom?
>>  uhid*       at uhidev?              # USB generic HID support
>>  fido*       at uhidev?              # FIDO/U2F security key support
>> +ucc*        at uhidev?              # Consumer Control keyboards
>> +wskbd*      at ucc? mux 1
>>  ujoy*       at uhidev?              # USB joystick/gamecontroller support
>>  uhidpp*     at uhidev?              # Logitech HID++ Devices
>>  upd*        at uhidev?              # USB Power Devices sensors
>> diff --git sys/arch/octeon/conf/GENERIC sys/arch/octeon/conf/GENERIC
>> index ec5424938cb..260b5fda752 100644
>> --- sys/arch/octeon/conf/GENERIC
>> +++ sys/arch/octeon/conf/GENERIC
>> @@ -156,6 +156,8 @@ uslhcom* at uhidev?      # Silicon Labs CP2110 USB HID 
>> UART
>>  ucom*               at uslhcom?
>>  uhid*               at uhidev?      # USB generic HID support
>>  fido*               at uhidev?      # FIDO/U2F security key support
>> +ucc*                at uhidev?      # Consumer Control keyboards
>> +wskbd*              at ucc? mux 1
>>  ujoy*               at uhidev?      # USB joystick/gamecontroller support
>>  uhidpp*             at uhidev?      # Logitech HID++ Devices
>>  upd*                at uhidev?      # USB Power Devices sensors
>> diff --git sys/arch/powerpc64/conf/GENERIC sys/arch/powerpc64/conf/GENERIC
>> index 5a41fb2ae72..311355bce1a 100644
>> --- sys/arch/powerpc64/conf/GENERIC
>> +++ sys/arch/powerpc64/conf/GENERIC
>> @@ -127,6 +127,8 @@ uslhcom* at uhidev?              # Silicon Labs CP2110 
>> USB HID UART
>>  ucom*       at uslhcom?
>>  uhid*       at uhidev?              # USB generic HID support
>>  fido*       at uhidev?              # FIDO/U2F security key support
>> +ucc*        at uhidev?              # Consumer Control keyboards
>> +wskbd*      at ucc? mux 1
>>  ujoy*       at uhidev?              # USB joystick/gamecontroller support
>>  uhidpp*     at uhidev?              # Logitech HID++ Devices
>>  upd*        at uhidev?              # USB Power Devices sensors
>> diff --git sys/arch/sparc64/conf/GENERIC sys/arch/sparc64/conf/GENERIC
>> index 71e92dc9016..757a637cc09 100644
>> --- sys/arch/sparc64/conf/GENERIC
>> +++ sys/arch/sparc64/conf/GENERIC
>> @@ -224,6 +224,8 @@ umsm*    at uhub?                # Qualcomm MSM EVDO
>>  ucom*       at umsm?
>>  uhid*       at uhidev?              # USB generic HID support
>>  fido*       at uhidev?              # FIDO/U2F security key support
>> +ucc*        at uhidev?              # Consumer Control keyboards
>> +wskbd*      at ucc? mux 1
>>  ujoy*       at uhidev?              # USB joystick/gamecontroller support
>>  uhidpp*     at uhidev?              # Logitech HID++ Devices
>>  upd*        at uhidev?              # USB Power Devices sensors
>> diff --git sys/dev/hid/hid.h sys/dev/hid/hid.h
>> index dd9586d7cc2..23f8f7979ec 100644
>> --- sys/dev/hid/hid.h
>> +++ sys/dev/hid/hid.h
>> @@ -397,6 +397,9 @@ int      hid_is_collection(const void *, int, uint8_t, 
>> int32_t);
>>  
>>  /* Usages, Consumer */
>>  #define HUC_CONTROL         0x0001
>> +#define HUC_TRACK_NEXT              0x00b5
>> +#define HUC_TRACK_PREV              0x00b6
>> +#define HUC_STOP            0x00b7
>>  #define HUC_PLAY_PAUSE              0x00cd
>>  #define HUC_MUTE            0x00e2
>>  #define HUC_VOL_INC         0x00e9
>> diff --git sys/dev/usb/files.usb sys/dev/usb/files.usb
>> index 4d79c5ea21a..c4c4688f00e 100644
>> --- sys/dev/usb/files.usb
>> +++ sys/dev/usb/files.usb
>> @@ -488,3 +488,8 @@ file     dev/usb/umstc.c                 umstc
>>  device      uhidpp: hid
>>  attach      uhidpp at uhidbus
>>  file        dev/usb/uhidpp.c                uhidpp
>> +
>> +# Consumer Control Keyboards
>> +device      ucc: hid, wskbddev
>> +attach      ucc at uhidbus
>> +file        dev/usb/ucc.c                   ucc
>> diff --git sys/dev/usb/ucc.c sys/dev/usb/ucc.c
>> new file mode 100644
>> index 00000000000..8eb82a09cfd
>> --- /dev/null
>> +++ sys/dev/usb/ucc.c
>> @@ -0,0 +1,470 @@
>> +/*  $OpenBSD$       */
>> +
>> +/*
>> + * Copyright (c) 2021 Anton Lindqvist <an...@openbsd.org>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for any
>> + * purpose with or without fee is hereby granted, provided that the above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/param.h>
>> +#include <sys/systm.h>
>> +#include <sys/device.h>
>> +#include <sys/malloc.h>
>> +
>> +#include <dev/usb/usb.h>
>> +#include <dev/usb/usbhid.h>
>> +#include <dev/usb/usbdi.h>
>> +#include <dev/usb/uhidev.h>
>> +
>> +#include <dev/wscons/wsconsio.h>
>> +#include <dev/wscons/wskbdvar.h>
>> +#include <dev/wscons/wsksymdef.h>
>> +#include <dev/wscons/wsksymvar.h>
>> +
>> +/* #define UCC_DEBUG */
>> +#ifdef UCC_DEBUG
>> +#define DPRINTF(x...)       do { if (ucc_debug) printf(x); } while (0)
>> +void        ucc_dump(const char *, u_char *, u_int);
>> +int ucc_debug = 1;
>> +#else
>> +#define DPRINTF(x...)
>> +#define ucc_dump(prefix, data, len)
>> +#endif
>> +
>> +struct ucc_softc {
>> +    struct uhidev            sc_hdev;
>> +    struct device           *sc_wskbddev;
>> +
>> +    /* Key mappings used in translating mode. */
>> +    keysym_t                *sc_map;
>> +    u_int                    sc_maplen;
>> +    u_int                    sc_mapsiz;
>> +    u_int                    sc_nkeys;
>> +
>> +    /* Key mappings used in raw mode. */
>> +    struct ucc_keyraw       *sc_raw;
>> +    u_int                    sc_rawlen;
>> +    u_int                    sc_rawsiz;
>> +
>> +    int                      sc_mode;
>> +
>> +    /* Last pressed key. */
>> +    union {
>> +            int     sc_last_translate;
>> +            u_char  sc_last_raw;
>> +    };
>> +
>> +    struct wscons_keydesc    sc_keydesc[2];
>> +    struct wskbd_mapdata     sc_keymap;
>> +};
>> +
>> +struct ucc_keysym {
>> +    int32_t         us_usage;
>> +    keysym_t        us_key;
>> +    u_char          us_raw;
>> +};
>> +
>> +struct ucc_keyraw {
>> +    u_int   ur_bit;
>> +    u_char  ur_raw;
>> +};
>> +
>> +int ucc_match(struct device *, void *, void *);
>> +void        ucc_attach(struct device *, struct device *, void *);
>> +int ucc_detach(struct device *, int);
>> +void        ucc_intr(struct uhidev *, void *, u_int);
>> +
>> +void        ucc_attach_wskbd(struct ucc_softc *);
>> +int ucc_enable(void *, int);
>> +void        ucc_set_leds(void *, int);
>> +int ucc_ioctl(void *, u_long, caddr_t, int, struct proc *);
>> +
>> +int ucc_parse_hid(struct ucc_softc *, void *, int);
>> +int ucc_bit_to_raw(struct ucc_softc *, u_int, u_char *);
>> +int ucc_usage_to_sym(int32_t, const struct ucc_keysym **);
>> +void        ucc_raw_to_scancode(u_char *, int *, u_char, int);
>> +void        ucc_input(struct ucc_softc *, u_int, int);
>> +void        ucc_rawinput(struct ucc_softc *, u_char, int);
>> +int ucc_setbits(u_char *, int, u_int *);
>> +
>> +struct cfdriver ucc_cd = {
>> +    NULL, "ucc", DV_DULL
>> +};
>> +
>> +const struct cfattach ucc_ca = {
>> +    sizeof(struct ucc_softc),
>> +    ucc_match,
>> +    ucc_attach,
>> +    ucc_detach,
>> +};
>> +
>> +/*
>> + * Mapping of HID consumer control usages to key symbols.
>> + * The raw scan codes are taken from X11, see the media_common symbols in
>> + * dist/xkeyboard-config/symbols/inet.
>> + * Then use dist/xkeyboard-config/keycodes/xfree86 to resolve keys to the
>> + * corrensponding raw scan code.
>> + */
>> +static const struct ucc_keysym ucc_keysyms[] = {
>> +    { HUC_MUTE,             KS_AudioMute,   0 },
>> +    { HUC_VOL_INC,          KS_AudioRaise,  0 },
>> +    { HUC_VOL_DEC,          KS_AudioLower,  0 },
>> +    { HUC_TRACK_NEXT,       0,              153 /* I19 = XF86AudioNext */ },
>> +    { HUC_TRACK_PREV,       0,              144 /* I10 = XF86AudioPrev */ },
>> +    { HUC_STOP,             0,              164 /* I24 = XF86AudioStop */ },
>> +    { HUC_PLAY_PAUSE,       0,              162 /* I22 = XF86AudioPlay, 
>> XF86AudioPause */ },
>> +};
>> +
>> +int
>> +ucc_match(struct device *parent, void *match, void *aux)
>> +{
>> +    struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
>> +    void *desc;
>> +    int size;
>> +
>> +    uhidev_get_report_desc(uha->parent, &desc, &size);
>> +    if (!hid_is_collection(desc, size, uha->reportid,
>> +        HID_USAGE2(HUP_CONSUMER, HUC_CONTROL)))
>> +            return UMATCH_NONE;
>> +
>> +    return UMATCH_IFACECLASS;
>> +}
>> +
>> +void
>> +ucc_attach(struct device *parent, struct device *self, void *aux)
>> +{
>> +    struct ucc_softc *sc = (struct ucc_softc *)self;
>> +    struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
>> +    void *desc;
>> +    int error, repid, size;
>> +
>> +    sc->sc_mode = WSKBD_TRANSLATED;
>> +    sc->sc_last_translate = -1;
>> +
>> +    sc->sc_hdev.sc_intr = ucc_intr;
>> +    sc->sc_hdev.sc_parent = uha->parent;
>> +    sc->sc_hdev.sc_udev = uha->uaa->device;
>> +    sc->sc_hdev.sc_report_id = uha->reportid;
>> +
>> +    uhidev_get_report_desc(uha->parent, &desc, &size);
>> +    repid = uha->reportid;
>> +    sc->sc_hdev.sc_isize = hid_report_size(desc, size, hid_input, repid);
>> +    sc->sc_hdev.sc_osize = hid_report_size(desc, size, hid_output, repid);
>> +    sc->sc_hdev.sc_fsize = hid_report_size(desc, size, hid_feature, repid);
>> +
>> +    error = ucc_parse_hid(sc, desc, size);
>> +    if (error) {
>> +            printf(" hid error %d\n", error);
>> +            return;
>> +    }
>> +
>> +    printf(" keys %d, mappings %d\n", sc->sc_nkeys, sc->sc_rawlen);
>> +
>> +    /* Cannot load an empty map. */
>> +    if (sc->sc_maplen > 0)
>> +            ucc_attach_wskbd(sc);
>> +}
>> +
>> +int
>> +ucc_detach(struct device *self, int flags)
>> +{
>> +    struct ucc_softc *sc = (struct ucc_softc *)self;
>> +    int error = 0;
>> +
>> +    if (sc->sc_wskbddev != NULL)
>> +            error = config_detach(sc->sc_wskbddev, flags);
>> +    uhidev_close(&sc->sc_hdev);
>> +    free(sc->sc_map, M_USBDEV, sc->sc_mapsiz);
>> +    free(sc->sc_raw, M_USBDEV, sc->sc_rawsiz);
>> +    return error;
>> +}
>> +
>> +void
>> +ucc_intr(struct uhidev *addr, void *data, u_int len)
>> +{
>> +    struct ucc_softc *sc = (struct ucc_softc *)addr;
>> +    int raw = sc->sc_mode == WSKBD_RAW;
>> +    u_int bit = 0;
>> +
>> +    ucc_dump(__func__, data, len);
>> +
>> +    if (ucc_setbits(data, len, &bit)) {
>> +            /* All zeroes, assume key up event. */
>> +            if (raw) {
>> +                    if (sc->sc_last_raw != 0) {
>> +                            ucc_rawinput(sc, sc->sc_last_raw, 1);
>> +                            sc->sc_last_raw = 0;
>> +                    }
>> +            } else {
>> +                    if (sc->sc_last_translate != -1) {
>> +                            ucc_input(sc, sc->sc_last_translate, 1);
>> +                            sc->sc_last_translate = -1;
>> +                    }
>> +            }
>> +            return;
>> +    }
>> +    if (bit >= sc->sc_nkeys)
>> +            goto unknown;
>> +
>> +    if (raw) {
>> +            u_char c;
>> +
>> +            if (ucc_bit_to_raw(sc, bit, &c))
>> +                    goto unknown;
>> +            if (c != 0) {
>> +                    ucc_rawinput(sc, c, 0);
>> +                    sc->sc_last_raw = c;
>> +                    return;
>> +            }
>> +
>> +            /*
>> +             * The pressed key does not have a corresponding raw scan code
>> +             * which implies that wsbkd must handle the pressed key as if
>> +             * being in translating mode, hence the fall through. This is
>> +             * only the case for volume related keys.
>> +             */
>> +    }
>> +
>> +    ucc_input(sc, bit, 0);
>> +    if (!raw)
>> +            sc->sc_last_translate = bit;
>> +    return;
>> +
>> +unknown:
>> +    DPRINTF("%s: unknown key: bit %d\n", __func__, bit);
>> +}
>> +
>> +void
>> +ucc_attach_wskbd(struct ucc_softc *sc)
>> +{
>> +    static const struct wskbd_accessops accessops = {
>> +            .enable         = ucc_enable,
>> +            .set_leds       = ucc_set_leds,
>> +            .ioctl          = ucc_ioctl,
>> +    };
>> +    struct wskbddev_attach_args a = {
>> +            .console        = 0,
>> +            .keymap         = &sc->sc_keymap,
>> +            .accessops      = &accessops,
>> +            .accesscookie   = sc,
>> +    };
>> +
>> +    sc->sc_keydesc[0].name = KB_US;
>> +    sc->sc_keydesc[0].base = 0;
>> +    sc->sc_keydesc[0].map_size = sc->sc_maplen;
>> +    sc->sc_keydesc[0].map = sc->sc_map;
>> +    sc->sc_keymap.keydesc = sc->sc_keydesc;
>> +    sc->sc_keymap.layout = KB_US | KB_DEFAULT;
>> +    sc->sc_wskbddev = config_found(&sc->sc_hdev.sc_dev, &a, wskbddevprint);
>> +}
>> +
>> +int
>> +ucc_enable(void *v, int on)
>> +{
>> +    struct ucc_softc *sc = (struct ucc_softc *)v;
>> +    int error = 0;
>> +
>> +    if (on)
>> +            error = uhidev_open(&sc->sc_hdev);
>> +    else
>> +            uhidev_close(&sc->sc_hdev);
>> +    return error;
>> +}
>> +
>> +void
>> +ucc_set_leds(void *v, int leds)
>> +{
>> +}
>> +
>> +int
>> +ucc_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
>> +{
>> +    struct ucc_softc *sc = (struct ucc_softc *)v;
>> +
>> +    switch (cmd) {
>> +#ifdef WSDISPLAY_COMPAT_RAWKBD
>> +    case WSKBDIO_SETMODE:
>> +            sc->sc_mode = *((int *)data);
>> +            return 0;
>> +#endif
>> +    }
>> +
>> +    return -1;
>> +}
>> +
>> +/*
>> + * Parse the HID report and construct a mapping between the bits in the 
>> input
>> + * report and the corresponding pressed key.
>> + */
>> +int
>> +ucc_parse_hid(struct ucc_softc *sc, void *desc, int descsiz)
>> +{
>> +    struct hid_item hi;
>> +    struct hid_data *hd;
>> +    int isize;
>> +
>> +    /*
>> +     * The size of the input report is expressed in bytes where each bit in
>> +     * turn represents a pressed key. It's likely that the number of keys is
>> +     * less than this generous estimate.
>> +     */
>> +    isize = sc->sc_hdev.sc_isize * 8;
>> +    if (isize == 0)
>> +            return ENXIO;
>> +
>> +    /*
>> +     * Create mapping between each input bit and the corresponding key used
>> +     * in translating mode. Two entries are needed per bit in order
>> +     * construct a mapping.
>> +     */
>> +    sc->sc_mapsiz = isize * 2 * sizeof(*sc->sc_map);
>> +    sc->sc_map = mallocarray(isize, 2 * sizeof(*sc->sc_map), M_USBDEV,
>> +        M_WAITOK | M_ZERO);
>> +
>> +    /*
>> +     * Create mapping between each input bit and the corresponding scan
>> +     * code used in raw mode.
>> +     */
>> +    sc->sc_rawsiz = isize * sizeof(*sc->sc_raw);
>> +    sc->sc_raw = mallocarray(isize, sizeof(*sc->sc_raw), M_USBDEV,
>> +        M_WAITOK | M_ZERO);
>> +
>> +    hd = hid_start_parse(desc, descsiz, hid_input);
>> +    while (hid_get_item(hd, &hi)) {
>> +            const struct ucc_keysym *us;
>> +            int bit;
>> +
>> +            if (HID_GET_USAGE_PAGE(hi.usage) != HUP_CONSUMER ||
>> +                HID_GET_USAGE(hi.usage) == HUC_CONTROL)
>> +                    continue;
>> +
>> +            bit = sc->sc_nkeys++;
>> +            if (ucc_usage_to_sym(HID_GET_USAGE(hi.usage), &us))
>> +                    continue;
>> +
>> +            if (sc->sc_maplen + 2 >= sc->sc_mapsiz)
>> +                    return ENOMEM;
>> +            sc->sc_map[sc->sc_maplen++] = KS_KEYCODE(bit);
>> +            sc->sc_map[sc->sc_maplen++] = us->us_key;
>> +
>> +            if (sc->sc_rawlen + 1 >= sc->sc_rawsiz)
>> +                    return ENOMEM;
>> +            sc->sc_raw[sc->sc_rawlen].ur_bit = bit;
>> +            sc->sc_raw[sc->sc_rawlen].ur_raw = us->us_raw;
>> +            sc->sc_rawlen++;
>> +
>> +            DPRINTF("%s: bit %d, usage %0x, key %0x\n", __func__,
>> +                bit, HID_GET_USAGE(hi.usage), us->us_key);
>> +    }
>> +    hid_end_parse(hd);
>> +
>> +    return 0;
>> +}
>> +
>> +int
>> +ucc_bit_to_raw(struct ucc_softc *sc, u_int bit, u_char *raw)
>> +{
>> +    u_int i;
>> +
>> +    for (i = 0; i < sc->sc_rawlen; i++) {
>> +            const struct ucc_keyraw *ur = &sc->sc_raw[i];
>> +
>> +            if (ur->ur_bit == bit) {
>> +                    *raw = ur->ur_raw;
>> +                    return 0;
>> +            }
>> +    }
>> +    return 1;
>> +}
>> +
>> +int
>> +ucc_usage_to_sym(int32_t usage, const struct ucc_keysym **us)
>> +{
>> +    int len = nitems(ucc_keysyms);
>> +    int i;
>> +
>> +    for (i = 0; i < len; i++) {
>> +            if (ucc_keysyms[i].us_usage == usage) {
>> +                    *us = &ucc_keysyms[i];
>> +                    return 0;
>> +            }
>> +    }
>> +    return 1;
>> +}
>> +
>> +void
>> +ucc_input(struct ucc_softc *sc, u_int bit, int release)
>> +{
>> +    int s;
>> +
>> +    s = spltty();
>> +    wskbd_input(sc->sc_wskbddev,
>> +        release ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN, bit);
>> +    splx(s);
>> +}
>> +
>> +void
>> +ucc_rawinput(struct ucc_softc *sc, u_char c, int release)
>> +{
>> +    u_char buf[2];
>> +    int len = 0;
>> +    int s;
>> +
>> +    if (c & 0x80)
>> +            buf[len++] = 0xe0;
>> +    buf[len++] = c & 0x7f;
>> +    if (release)
>> +            buf[len - 1] |= 0x80;
>> +
>> +    s = spltty();
>> +    wskbd_rawinput(sc->sc_wskbddev, buf, len);
>> +    splx(s);
>> +}
>> +
>> +int
>> +ucc_setbits(u_char *data, int len, u_int *bit)
>> +{
>> +    int i, j;
>> +
>> +    for (i = 0; i < len; i++) {
>> +            if (data[i] == 0)
>> +                    continue;
>> +
>> +            for (j = 0; j < 8; j++) {
>> +                    if (data[i] & (1 << j)) {
>> +                            *bit = (i * 8) + j;
>> +                            return 0;
>> +                    }
>> +            }
>> +    }
>> +
>> +    return 1;
>> +}
>> +
>> +#ifdef UCC_DEBUG
>> +
>> +void
>> +ucc_dump(const char *prefix, u_char *data, u_int len)
>> +{
>> +    u_int i;
>> +
>> +    if (ucc_debug == 0)
>> +            return;
>> +
>> +    printf("%s:", prefix);
>> +    for (i = 0; i < len; i++)
>> +            printf(" %02x", data[i]);
>> +    printf("\n");
>> +}
>> +
>> +#endif
>>
-- 
---
David Rinehart
wda...@cox.net


Reply via email to