From 552d8a60da77e7503ac846bbe9427b0d2cb034e2 Mon Sep 17 00:00:00 2001 From: anton Date: Fri, 11 Nov 2022 06:48:38 +0000 Subject: [PATCH] Make ucc(4) the first consumer of hidcc. No intended functional change. ok matthieu@ --- sys/dev/usb/files.usb | 4 +- sys/dev/usb/ucc.c | 1155 +---------------------------------------- 2 files changed, 23 insertions(+), 1136 deletions(-) diff --git a/sys/dev/usb/files.usb b/sys/dev/usb/files.usb index 6247848b830..88fff1b7c0f 100644 --- a/sys/dev/usb/files.usb +++ b/sys/dev/usb/files.usb @@ -1,4 +1,4 @@ -# $OpenBSD: files.usb,v 1.149 2022/01/09 05:43:00 jsg Exp $ +# $OpenBSD: files.usb,v 1.150 2022/11/11 06:48:38 anton Exp $ # $NetBSD: files.usb,v 1.16 2000/02/14 20:29:54 augustss Exp $ # # Config file and device description for machine-independent USB code. @@ -499,6 +499,6 @@ attach uhidpp at uhidbus file dev/usb/uhidpp.c uhidpp # Consumer Control Keyboards -device ucc: hid, wskbddev +device ucc: hid, hidcc, wskbddev attach ucc at uhidbus file dev/usb/ucc.c ucc diff --git a/sys/dev/usb/ucc.c b/sys/dev/usb/ucc.c index 4dff13034c1..acc14ce86cf 100644 --- a/sys/dev/usb/ucc.c +++ b/sys/dev/usb/ucc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ucc.c,v 1.35 2022/08/11 09:22:38 anton Exp $ */ +/* $OpenBSD: ucc.c,v 1.36 2022/11/11 06:48:38 anton Exp $ */ /* * Copyright (c) 2021 Anton Lindqvist @@ -18,88 +18,17 @@ #include #include -#include -#include #include #include #include #include -#include -#include -#include -#include - -#define DEVNAME(sc) ((sc)->sc_hdev.sc_dev.dv_xname) - -/* #define UCC_DEBUG */ -#ifdef UCC_DEBUG -#define DPRINTF(x...) do { if (ucc_debug) printf(x); } while (0) -struct ucc_softc; -void ucc_dump(struct ucc_softc *, const char *, uint8_t *, u_int); -int ucc_debug = 1; -#else -#define DPRINTF(x...) -#define ucc_dump(sc, prefix, data, len) -#endif +#include 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; - - /* Key mappings used in raw mode. */ - const struct ucc_keysym **sc_raw; - u_int sc_rawsiz; - - u_int sc_nusages; - int sc_isarray; - int sc_mode; - - /* - * Slice of the interrupt buffer which represents a pressed key. - * See section 8 (Report Protocol) of the HID specification v1.11. - */ - struct { - uint8_t *i_buf; - uint32_t i_bufsiz; - uint32_t i_off; /* offset in bits */ - uint32_t i_len; /* length in bits */ - } sc_input; - - struct { - uint32_t v_inc; /* volume increment bit offset */ - uint32_t v_dec; /* volume decrement bit offset */ - uint32_t v_off; /* offset in bits */ - uint32_t v_len; /* length in bits */ - } sc_volume; - - /* Last pressed key. */ - union { - int sc_last_translate; - u_char sc_last_raw; - }; - - /* - * Only the first element is populated whereas the second remains zeroed - * out since such trailing sentinel is required by wskbd_load_keymap(). - */ - struct wscons_keydesc sc_keydesc[2]; - struct wskbd_mapdata sc_keymap; -}; - -struct ucc_keysym { -#ifdef UCC_DEBUG - const char *us_name; -#endif - int32_t us_usage; - keysym_t us_key; - u_char us_raw; + struct uhidev sc_hdev; + struct hidcc *sc_cc; }; int ucc_match(struct device *, void *, void *); @@ -107,26 +36,7 @@ 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 *, void *); int ucc_enable(void *, int); -void ucc_set_leds(void *, int); -int ucc_ioctl(void *, u_long, caddr_t, int, struct proc *); - -int ucc_hid_match(void *, int, uint8_t); -int ucc_hid_parse(struct ucc_softc *, void *, int); -int ucc_hid_parse_array(struct ucc_softc *, const struct hid_item *); -int ucc_hid_is_array(const struct hid_item *); -int ucc_add_key(struct ucc_softc *, int32_t, u_int); -int ucc_add_key_volume(struct ucc_softc *, const struct hid_item *, - uint32_t, u_int); -int ucc_bit_to_sym(struct ucc_softc *, u_int, const struct ucc_keysym **); -int ucc_usage_to_sym(int32_t, const struct ucc_keysym **); -int ucc_bits_to_int(uint8_t *, u_int, int32_t *); -int ucc_bits_to_volume(struct ucc_softc *, uint8_t *, int, u_int *); -int ucc_intr_slice(struct ucc_softc *, uint8_t *, uint8_t *, int *); -void ucc_input(struct ucc_softc *, u_int, int); -void ucc_rawinput(struct ucc_softc *, u_char, int); -int ucc_setbits(struct ucc_softc *, uint8_t *, int, u_int *); struct cfdriver ucc_cd = { NULL, "ucc", DV_DULL @@ -139,496 +49,6 @@ const struct cfattach ucc_ca = { ucc_detach, }; -/* - * Mapping of HID Consumer Control usages to key symbols based on the HID Usage - * Tables 1.21 specification. The same usages can also be found at - * /usr/share/misc/usb_hid_usages. - * The raw scan codes are taken from X11, see the media_nav_acpi_common symbols - * in dist/xkeyboard-config/symbols/inet. - * Then use dist/xkeyboard-config/keycodes/xfree86 to resolve keys to the - * corresponding raw scan code. - */ -static const struct ucc_keysym ucc_keysyms[] = { -#ifdef UCC_DEBUG -#define Y(usage, name, key, raw) { name, usage, key, raw }, -#else -#define Y(usage, name, key, raw) { usage, key, raw }, -#endif -#define N(usage, name, key, raw) - /* 0x0000 Unassigned */ - N(0x0001, "Consumer Control", 0, 0) - N(0x0002, "Numeric Key Pad", 0, 0) - N(0x0003, "Programmable Buttons", 0, 0) - N(0x0004, "Microphone", 0, 0) - N(0x0005, "Headphone", 0, 0) - N(0x0006, "Graphic Equalizer", 0, 0) - /* 0x0007-0x001F Reserved */ - N(0x0020, "+10", 0, 0) - N(0x0021, "+100", 0, 0) - N(0x0022, "AM/PM", 0, 0) - /* 0x0023-0x002F Reserved */ - Y(0x0030, "Power", 0, 222 /* I5E = XF86PowerOff */) - N(0x0031, "Reset", 0, 0) - Y(0x0032, "Sleep", 0, 150 /* I16 = XF86Sleep */) - N(0x0033, "Sleep After", 0, 0) - N(0x0034, "Sleep Mode", 0, 0) - N(0x0035, "Illumination", 0, 0) - N(0x0036, "Function Buttons", 0, 0) - /* 0x0037-0x003F Reserved */ - N(0x0040, "Menu", 0, 0) - N(0x0041, "Menu Pick", 0, 0) - N(0x0042, "Menu Up", 0, 0) - N(0x0043, "Menu Down", 0, 0) - N(0x0044, "Menu Left", 0, 0) - N(0x0045, "Menu Right", 0, 0) - N(0x0046, "Menu Escape", 0, 0) - N(0x0047, "Menu Value Increase", 0, 0) - N(0x0048, "Menu Value Decrease", 0, 0) - /* 0x0049-0x005F Reserved */ - N(0x0060, "Data On Screen", 0, 0) - N(0x0061, "Closed Caption", 0, 0) - N(0x0062, "Closed Caption Select", 0, 0) - N(0x0063, "VCR/TV", 0, 0) - N(0x0064, "Broadcast Mode", 0, 0) - N(0x0065, "Snapshot", 0, 0) - N(0x0066, "Still", 0, 0) - N(0x0067, "Picture-in-Picture Toggle", 0, 0) - N(0x0068, "Picture-in-Picture Swap", 0, 0) - N(0x0069, "Red Menu Button", 0, 0) - N(0x006A, "Green Menu Button", 0, 0) - N(0x006B, "Blue Menu Button", 0, 0) - N(0x006C, "Yellow Menu Button", 0, 0) - N(0x006D, "Aspect", 0, 0) - N(0x006E, "3D Mode Select", 0, 0) - N(0x006F, "Display Brightness Increment", 0, 0) - N(0x0070, "Display Brightness Decrement", 0, 0) - N(0x0071, "Display Brightness", 0, 0) - N(0x0072, "Display Backlight Toggle", 0, 0) - N(0x0073, "Display Set Brightness to Minimum", 0, 0) - N(0x0074, "Display Set Brightness to Maximum", 0, 0) - N(0x0075, "Display Set Auto Brightness", 0, 0) - N(0x0076, "Camera Access Enabled", 0, 0) - N(0x0077, "Camera Access Disabled", 0, 0) - N(0x0078, "Camera Access Toggle", 0, 0) - N(0x0079, "Keyboard Brightness Increment", 0, 0) - N(0x007A, "Keyboard Brightness Decrement", 0, 0) - N(0x007B, "Keyboard Backlight Set Level", 0, 0) - N(0x007C, "Keyboard Backlight OOC", 0, 0) - N(0x007D, "Keyboard Backlight Set Minimum", 0, 0) - N(0x007E, "Keyboard Backlight Set Maximum", 0, 0) - N(0x007F, "Keyboard Backlight Auto", 0, 0) - N(0x0080, "Selection", 0, 0) - N(0x0081, "Assign Selection", 0, 0) - N(0x0082, "Mode Step", 0, 0) - N(0x0083, "Recall Last", 0, 0) - N(0x0084, "Enter Channel", 0, 0) - N(0x0085, "Order Movie", 0, 0) - N(0x0086, "Channel", 0, 0) - N(0x0087, "Media Selection", 0, 0) - N(0x0088, "Media Select Computer", 0, 0) - N(0x0089, "Media Select TV", 0, 0) - N(0x008A, "Media Select WWW", 0, 0) - N(0x008B, "Media Select DVD", 0, 0) - N(0x008C, "Media Select Telephone", 0, 0) - N(0x008D, "Media Select Program Guide", 0, 0) - N(0x008E, "Media Select Video Phone", 0, 0) - N(0x008F, "Media Select Games", 0, 0) - N(0x0090, "Media Select Messages", 0, 0) - N(0x0091, "Media Select CD", 0, 0) - N(0x0092, "Media Select VCR", 0, 0) - N(0x0093, "Media Select Tuner", 0, 0) - N(0x0094, "Quit", 0, 0) - N(0x0095, "Help", 0, 0) - N(0x0096, "Media Select Tape", 0, 0) - N(0x0097, "Media Select Cable", 0, 0) - N(0x0098, "Media Select Satellite", 0, 0) - N(0x0099, "Media Select Security", 0, 0) - N(0x009A, "Media Select Home", 0, 0) - N(0x009B, "Media Select Call", 0, 0) - N(0x009C, "Channel Increment", 0, 0) - N(0x009D, "Channel Decrement", 0, 0) - N(0x009E, "Media Select SAP", 0, 0) - /* 0x009F-0x009F Reserved */ - N(0x00A0, "VCR Plus", 0, 0) - N(0x00A1, "Once", 0, 0) - N(0x00A2, "Daily", 0, 0) - N(0x00A3, "Weekly", 0, 0) - N(0x00A4, "Monthly", 0, 0) - /* 0x00A5-0x00AF Reserved */ - N(0x00B0, "Play", 0, 0) - N(0x00B1, "Pause", 0, 0) - N(0x00B2, "Record", 0, 0) - N(0x00B3, "Fast Forward", 0, 0) - N(0x00B4, "Rewind", 0, 0) - Y(0x00B5, "Scan Next Track", 0, 153 /* I19 = XF86AudioNext */) - Y(0x00B6, "Scan Previous Track", 0, 144 /* I10 = XF86AudioPrev */) - Y(0x00B7, "Stop", 0, 164 /* I24 = XF86AudioStop */) - Y(0x00B8, "Eject", 0, 170 /* K5A = XF86Eject */) - N(0x00B9, "Random Play", 0, 0) - N(0x00BA, "Select Disc", 0, 0) - N(0x00BB, "Enter Disc", 0, 0) - N(0x00BC, "Repeat", 0, 0) - N(0x00BD, "Tracking", 0, 0) - N(0x00BE, "Track Normal", 0, 0) - N(0x00BF, "Slow Tracking", 0, 0) - N(0x00C0, "Frame Forward", 0, 0) - N(0x00C1, "Frame Back", 0, 0) - N(0x00C2, "Mark", 0, 0) - N(0x00C3, "Clear Mark", 0, 0) - N(0x00C4, "Repeat From Mark", 0, 0) - N(0x00C5, "Return To Mark", 0, 0) - N(0x00C6, "Search Mark Forward", 0, 0) - N(0x00C7, "Search Mark Backwards", 0, 0) - N(0x00C8, "Counter Reset", 0, 0) - N(0x00C9, "Show Counter", 0, 0) - N(0x00CA, "Tracking Increment", 0, 0) - N(0x00CB, "Tracking Decrement", 0, 0) - N(0x00CC, "Stop/Eject", 0, 0) - Y(0x00CD, "Play/Pause", 0, 162 /* I22 = XF86AudioPlay */) - N(0x00CE, "Play/Skip", 0, 0) - N(0x00CF, "Voice Command", 0, 0) - N(0x00D0, "Invoke Capture Interface", 0, 0) - N(0x00D1, "Start or Stop Game Recording", 0, 0) - N(0x00D2, "Historical Game Capture", 0, 0) - N(0x00D3, "Capture Game Screenshot", 0, 0) - N(0x00D4, "Show or Hide Recording Indicator", 0, 0) - N(0x00D5, "Start or Stop Microphone Capture", 0, 0) - N(0x00D6, "Start or Stop Camera Capture", 0, 0) - N(0x00D7, "Start or Stop Game Broadcast", 0, 0) - /* 0x00D8-0x00DF Reserved */ - N(0x00E0, "Volume", 0, 0) - N(0x00E1, "Balance", 0, 0) - Y(0x00E2, "Mute", KS_AudioMute, 160 /* I20 = XF86AudioMute */) - N(0x00E3, "Bass", 0, 0) - N(0x00E4, "Treble", 0, 0) - N(0x00E5, "Bass Boost", 0, 0) - N(0x00E6, "Surround Mode", 0, 0) - N(0x00E7, "Loudness", 0, 0) - N(0x00E8, "MPX", 0, 0) - Y(0x00E9, "Volume Increment", KS_AudioRaise, 176 /* I30 = XF86AudioRaiseVolume */) - Y(0x00EA, "Volume Decrement", KS_AudioLower, 174 /* I2E = XF86AudioLowerVolume */) - /* 0x00EB-0x00EF Reserved */ - N(0x00F0, "Speed Select", 0, 0) - N(0x00F1, "Playback Speed", 0, 0) - N(0x00F2, "Standard Play", 0, 0) - N(0x00F3, "Long Play", 0, 0) - N(0x00F4, "Extended Play", 0, 0) - N(0x00F5, "Slow", 0, 0) - /* 0x00F6-0x00FF Reserved */ - N(0x0100, "Fan Enable", 0, 0) - N(0x0101, "Fan Speed", 0, 0) - N(0x0102, "Light Enable", 0, 0) - N(0x0103, "Light Illumination Level", 0, 0) - N(0x0104, "Climate Control Enable", 0, 0) - N(0x0105, "Room Temperature", 0, 0) - N(0x0106, "Security Enable", 0, 0) - N(0x0107, "Fire Alarm", 0, 0) - N(0x0108, "Police Alarm", 0, 0) - N(0x0109, "Proximity", 0, 0) - N(0x010A, "Motion", 0, 0) - N(0x010B, "Duress Alarm", 0, 0) - N(0x010C, "Holdup Alarm", 0, 0) - N(0x010D, "Medical Alarm", 0, 0) - /* 0x010E-0x014F Reserved */ - N(0x0150, "Balance Right", 0, 0) - N(0x0151, "Balance Left", 0, 0) - N(0x0152, "Bass Increment", 0, 0) - N(0x0153, "Bass Decrement", 0, 0) - N(0x0154, "Treble Increment", 0, 0) - N(0x0155, "Treble Decrement", 0, 0) - /* 0x0156-0x015F Reserved */ - N(0x0160, "Speaker System", 0, 0) - N(0x0161, "Channel Left", 0, 0) - N(0x0162, "Channel Right", 0, 0) - N(0x0163, "Channel Center", 0, 0) - N(0x0164, "Channel Front", 0, 0) - N(0x0165, "Channel Center Front", 0, 0) - N(0x0166, "Channel Side", 0, 0) - N(0x0167, "Channel Surround", 0, 0) - N(0x0168, "Channel Low Frequency Enhancement", 0, 0) - N(0x0169, "Channel Top", 0, 0) - N(0x016A, "Channel Unknown", 0, 0) - /* 0x016B-0x016F Reserved */ - N(0x0170, "Sub-channel", 0, 0) - N(0x0171, "Sub-channel Increment", 0, 0) - N(0x0172, "Sub-channel Decrement", 0, 0) - N(0x0173, "Alternate Audio Increment", 0, 0) - N(0x0174, "Alternate Audio Decrement", 0, 0) - /* 0x0175-0x017F Reserved */ - N(0x0180, "Application Launch Buttons", 0, 0) - N(0x0181, "AL Launch Button Configuration Tool", 0, 0) - N(0x0182, "AL Programmable Button Configuration", 0, 0) - N(0x0183, "AL Consumer Control Configuration", 0, 0) - N(0x0184, "AL Word Processor", 0, 0) - N(0x0185, "AL Text Editor", 0, 0) - N(0x0186, "AL Spreadsheet", 0, 0) - N(0x0187, "AL Graphics Editor", 0, 0) - N(0x0188, "AL Presentation App", 0, 0) - N(0x0189, "AL Database App", 0, 0) - Y(0x018A, "AL Email Reader", 0, 235 /* I6C = XF86Mail */) - N(0x018B, "AL Newsreader", 0, 0) - N(0x018C, "AL Voicemail", 0, 0) - N(0x018D, "AL Contacts/Address Book", 0, 0) - N(0x018E, "AL Calendar/Schedule", 0, 0) - N(0x018F, "AL Task/Project Manager", 0, 0) - N(0x0190, "AL Log/Journal/Timecard", 0, 0) - N(0x0191, "AL Checkbook/Finance", 0, 0) - Y(0x0192, "AL Calculator", 0, 161 /* I21 = XF86Calculator */) - N(0x0193, "AL A/V Capture/Playback", 0, 0) - N(0x0194, "AL Local Machine Browser", 0, 0) - N(0x0195, "AL LAN/WAN Browser", 0, 0) - Y(0x0196, "AL Internet Browser", 0, 178 /* I32 = XF86WWW */) - N(0x0197, "AL Remote Networking/ISP Connect", 0, 0) - N(0x0198, "AL Network Conference", 0, 0) - N(0x0199, "AL Network Chat", 0, 0) - N(0x019A, "AL Telephony/Dialer", 0, 0) - N(0x019B, "AL Logon", 0, 0) - N(0x019C, "AL Logoff", 0, 0) - N(0x019D, "AL Logon/Logoff", 0, 0) - N(0x019E, "AL Terminal Lock/Screensaver", 0, 0) - N(0x019F, "AL Control Panel", 0, 0) - N(0x01A0, "AL Command Line Processor/Run", 0, 0) - N(0x01A1, "AL Process/Task Manager", 0, 0) - N(0x01A2, "AL Select Task/Application", 0, 0) - N(0x01A3, "AL Next Task/Application", 0, 0) - N(0x01A4, "AL Previous Task/Application", 0, 0) - N(0x01A5, "AL Preemptive Halt Task/Application", 0, 0) - N(0x01A6, "AL Integrated Help Center", 0, 0) - N(0x01A7, "AL My Documents", 0, 0) - N(0x01A8, "AL Thesaurus", 0, 0) - N(0x01A9, "AL Dictionary", 0, 0) - N(0x01AA, "AL Desktop", 0, 0) - N(0x01AB, "AC Spell", 0, 0) - N(0x01AC, "AL Grammar Check", 0, 0) - N(0x01AD, "AL Wireless Status", 0, 0) - N(0x01AE, "AL Keyboard Layout", 0, 0) - N(0x01AF, "AL Virus Protection", 0, 0) - N(0x01B0, "AL Encryption", 0, 0) - N(0x01B1, "AL Screen Saver", 0, 0) - N(0x01B2, "AL Alarms", 0, 0) - N(0x01B3, "AL Clock", 0, 0) - N(0x01B4, "AL File Browser", 0, 0) - N(0x01B5, "AL Power Status", 0, 0) - N(0x01B6, "AL My Pictures", 0, 0) - N(0x01B7, "AL My Music", 0, 0) - N(0x01B8, "AL Movie Browser", 0, 0) - N(0x01B9, "AL Digital Rights Manager", 0, 0) - N(0x01BA, "AL Digital Wallet", 0, 0) - /* 0x01BB-0x01BB Reserved */ - N(0x01BC, "AL Instant Messaging", 0, 0) - N(0x01BD, "AL OEM Feature/Tips/Tutorial Browser", 0, 0) - N(0x01BE, "AL OEM Help", 0, 0) - N(0x01BF, "AL Online Community", 0, 0) - N(0x01C0, "AL Entertainment Content Browser", 0, 0) - N(0x01C1, "AL Online Shopping Browser", 0, 0) - N(0x01C2, "AL SmartCard Information/Help", 0, 0) - N(0x01C3, "AL Market Monitor/Finance Browser", 0, 0) - N(0x01C4, "AL Customized Corporate News Browser", 0, 0) - N(0x01C5, "AL Online Activity Browser", 0, 0) - Y(0x01C6, "AL Research/Search Browser", 0, 229 /* I65 = XF86Search */) - N(0x01C7, "AL Audio Player", 0, 0) - N(0x01C8, "AL Message Status", 0, 0) - N(0x01C9, "AL Contact Sync", 0, 0) - N(0x01CA, "AL Navigation", 0, 0) - N(0x01CB, "AL Context-aware Desktop Assistant", 0, 0) - /* 0x01CC-0x01FF Reserved */ - N(0x0200, "Generic GUI Application Controls", 0, 0) - N(0x0201, "AC New", 0, 0) - N(0x0202, "AC Open", 0, 0) - N(0x0203, "AC Close", 0, 0) - N(0x0204, "AC Exit", 0, 0) - N(0x0205, "AC Maximize", 0, 0) - N(0x0206, "AC Minimize", 0, 0) - N(0x0207, "AC Save", 0, 0) - N(0x0208, "AC Print", 0, 0) - N(0x0209, "AC Properties", 0, 0) - /* 0x020A-0x0219 Reserved */ - N(0x021A, "AC Undo", 0, 0) - N(0x021B, "AC Copy", 0, 0) - N(0x021C, "AC Cut", 0, 0) - N(0x021D, "AC Paste", 0, 0) - N(0x021E, "AC Select All", 0, 0) - N(0x021F, "AC Find", 0, 0) - N(0x0220, "AC Find and Replace", 0, 0) - N(0x0221, "AC Search", 0, 0) - N(0x0222, "AC Go To", 0, 0) - N(0x0223, "AC Home", 0, 0) - Y(0x0224, "AC Back", 0, 234 /* I6A = XF86Back */) - Y(0x0225, "AC Forward", 0, 233 /* I69 = XF86Forward */) - Y(0x0226, "AC Stop", 0, 232 /* I68 = XF86Stop */) - Y(0x0227, "AC Refresh", 0, 231 /* I67 = XF86Reload */) - N(0x0228, "AC Previous Link", 0, 0) - N(0x0229, "AC Next Link", 0, 0) - N(0x022A, "AC Bookmarks", 0, 0) - N(0x022B, "AC History", 0, 0) - N(0x022C, "AC Subscriptions", 0, 0) - N(0x022D, "AC Zoom In", 0, 0) - N(0x022E, "AC Zoom Out", 0, 0) - N(0x022F, "AC Zoom", 0, 0) - N(0x0230, "AC Full Screen View", 0, 0) - N(0x0231, "AC Normal View", 0, 0) - N(0x0232, "AC View Toggle", 0, 0) - N(0x0233, "AC Scroll Up", 0, 0) - N(0x0234, "AC Scroll Down", 0, 0) - N(0x0235, "AC Scroll", 0, 0) - N(0x0236, "AC Pan Left", 0, 0) - N(0x0237, "AC Pan Right", 0, 0) - N(0x0238, "AC Pan", 0, 0) - N(0x0239, "AC New Window", 0, 0) - N(0x023A, "AC Tile Horizontally", 0, 0) - N(0x023B, "AC Tile Vertically", 0, 0) - N(0x023C, "AC Format", 0, 0) - N(0x023D, "AC Edit", 0, 0) - N(0x023E, "AC Bold", 0, 0) - N(0x023F, "AC Italics", 0, 0) - N(0x0240, "AC Underline", 0, 0) - N(0x0241, "AC Strikethrough", 0, 0) - N(0x0242, "AC Subscript", 0, 0) - N(0x0243, "AC Superscript", 0, 0) - N(0x0244, "AC All Caps", 0, 0) - N(0x0245, "AC Rotate", 0, 0) - N(0x0246, "AC Resize", 0, 0) - N(0x0247, "AC Flip Horizontal", 0, 0) - N(0x0248, "AC Flip Vertical", 0, 0) - N(0x0249, "AC Mirror Horizontal", 0, 0) - N(0x024A, "AC Mirror Vertical", 0, 0) - N(0x024B, "AC Font Select", 0, 0) - N(0x024C, "AC Font Color", 0, 0) - N(0x024D, "AC Font Size", 0, 0) - N(0x024E, "AC Justify Left", 0, 0) - N(0x024F, "AC Justify Center H", 0, 0) - N(0x0250, "AC Justify Right", 0, 0) - N(0x0251, "AC Justify Block H", 0, 0) - N(0x0252, "AC Justify Top", 0, 0) - N(0x0253, "AC Justify Center V", 0, 0) - N(0x0254, "AC Justify Bottom", 0, 0) - N(0x0255, "AC Justify Block V", 0, 0) - N(0x0256, "AC Justify Decrease", 0, 0) - N(0x0257, "AC Justify Increase", 0, 0) - N(0x0258, "AC Numbered List", 0, 0) - N(0x0259, "AC Restart Numbering", 0, 0) - N(0x025A, "AC Bulleted List", 0, 0) - N(0x025B, "AC Promote", 0, 0) - N(0x025C, "AC Demote", 0, 0) - N(0x025D, "AC Yes", 0, 0) - N(0x025E, "AC No", 0, 0) - N(0x025F, "AC Cancel", 0, 0) - N(0x0260, "AC Catalog", 0, 0) - N(0x0261, "AC Buy/Checkout", 0, 0) - N(0x0262, "AC Add to Cart", 0, 0) - N(0x0263, "AC Expand", 0, 0) - N(0x0264, "AC Expand All", 0, 0) - N(0x0265, "AC Collapse", 0, 0) - N(0x0266, "AC Collapse All", 0, 0) - N(0x0267, "AC Print Preview", 0, 0) - N(0x0268, "AC Paste Special", 0, 0) - N(0x0269, "AC Insert Mode", 0, 0) - N(0x026A, "AC Delete", 0, 0) - N(0x026B, "AC Lock", 0, 0) - N(0x026C, "AC Unlock", 0, 0) - N(0x026D, "AC Protect", 0, 0) - N(0x026E, "AC Unprotect", 0, 0) - N(0x026F, "AC Attach Comment", 0, 0) - N(0x0270, "AC Delete Comment", 0, 0) - N(0x0271, "AC View Comment", 0, 0) - N(0x0272, "AC Select Word", 0, 0) - N(0x0273, "AC Select Sentence", 0, 0) - N(0x0274, "AC Select Paragraph", 0, 0) - N(0x0275, "AC Select Column", 0, 0) - N(0x0276, "AC Select Row", 0, 0) - N(0x0277, "AC Select Table", 0, 0) - N(0x0278, "AC Select Object", 0, 0) - N(0x0279, "AC Redo/Repeat", 0, 0) - N(0x027A, "AC Sort", 0, 0) - N(0x027B, "AC Sort Ascending", 0, 0) - N(0x027C, "AC Sort Descending", 0, 0) - N(0x027D, "AC Filter", 0, 0) - N(0x027E, "AC Set Clock", 0, 0) - N(0x027F, "AC View Clock", 0, 0) - N(0x0280, "AC Select Time Zone", 0, 0) - N(0x0281, "AC Edit Time Zones", 0, 0) - N(0x0282, "AC Set Alarm", 0, 0) - N(0x0283, "AC Clear Alarm", 0, 0) - N(0x0284, "AC Snooze Alarm", 0, 0) - N(0x0285, "AC Reset Alarm", 0, 0) - N(0x0286, "AC Synchronize", 0, 0) - N(0x0287, "AC Send/Receive", 0, 0) - N(0x0288, "AC Send To", 0, 0) - N(0x0289, "AC Reply", 0, 0) - N(0x028A, "AC Reply All", 0, 0) - N(0x028B, "AC Forward Message", 0, 0) - N(0x028C, "AC Send", 0, 0) - N(0x028D, "AC Attach File", 0, 0) - N(0x028E, "AC Upload", 0, 0) - N(0x028F, "AC Download (Save Target As)", 0, 0) - N(0x0290, "AC Set Borders", 0, 0) - N(0x0291, "AC Insert Row", 0, 0) - N(0x0292, "AC Insert Column", 0, 0) - N(0x0293, "AC Insert File", 0, 0) - N(0x0294, "AC Insert Picture", 0, 0) - N(0x0295, "AC Insert Object", 0, 0) - N(0x0296, "AC Insert Symbol", 0, 0) - N(0x0297, "AC Save and Close", 0, 0) - N(0x0298, "AC Rename", 0, 0) - N(0x0299, "AC Merge", 0, 0) - N(0x029A, "AC Split", 0, 0) - N(0x029B, "AC Distribute Horizontally", 0, 0) - N(0x029C, "AC Distribute Vertically", 0, 0) - N(0x029D, "AC Next Keyboard Layout Select", 0, 0) - N(0x029E, "AC Navigation Guidance", 0, 0) - N(0x029F, "AC Desktop Show All Windows", 0, 0) - N(0x02A0, "AC Soft Key Left", 0, 0) - N(0x02A1, "AC Soft Key Right", 0, 0) - N(0x02A2, "AC Desktop Show All Applications", 0, 0) - /* 0x02A3-0x02AF Reserved */ - N(0x02B0, "AC Idle Keep Alive", 0, 0) - /* 0x02B1-0x02BF Reserved */ - N(0x02C0, "Extended Keyboard Attributes Collection", 0, 0) - N(0x02C1, "Keyboard Form Factor", 0, 0) - N(0x02C2, "Keyboard Key Type", 0, 0) - N(0x02C3, "Keyboard Physical Layout", 0, 0) - N(0x02C4, "Vendor-Specific Keyboard Physical Layout", 0, 0) - N(0x02C5, "Keyboard IETF Language Tag Index", 0, 0) - N(0x02C6, "Implemented Keyboard Input Assist Controls", 0, 0) - N(0x02C7, "Keyboard Input Assist Previous", 0, 0) - N(0x02C8, "Keyboard Input Assist Next", 0, 0) - N(0x02C9, "Keyboard Input Assist Previous Group", 0, 0) - N(0x02CA, "Keyboard Input Assist Next Group", 0, 0) - N(0x02CB, "Keyboard Input Assist Accept", 0, 0) - N(0x02CC, "Keyboard Input Assist Cancel", 0, 0) - /* 0x02CD-0x02CF Reserved */ - N(0x02D0, "Privacy Screen Toggle", 0, 0) - N(0x02D1, "Privacy Screen Level Decrement", 0, 0) - N(0x02D2, "Privacy Screen Level Increment", 0, 0) - N(0x02D3, "Privacy Screen Level Minimum", 0, 0) - N(0x02D4, "Privacy Screen Level Maximum", 0, 0) - /* 0x02D5-0x04FF Reserved */ - N(0x0500, "Contact Edited", 0, 0) - N(0x0501, "Contact Added", 0, 0) - N(0x0502, "Contact Record Active", 0, 0) - N(0x0503, "Contact Index", 0, 0) - N(0x0504, "Contact Nickname", 0, 0) - N(0x0505, "Contact First Name", 0, 0) - N(0x0506, "Contact Last Name", 0, 0) - N(0x0507, "Contact Full Name", 0, 0) - N(0x0508, "Contact Phone Number Personal", 0, 0) - N(0x0509, "Contact Phone Number Business", 0, 0) - N(0x050A, "Contact Phone Number Mobile", 0, 0) - N(0x050B, "Contact Phone Number Pager", 0, 0) - N(0x050C, "Contact Phone Number Fax", 0, 0) - N(0x050D, "Contact Phone Number Other", 0, 0) - N(0x050E, "Contact Email Personal", 0, 0) - N(0x050F, "Contact Email Business", 0, 0) - N(0x0510, "Contact Email Other", 0, 0) - N(0x0511, "Contact Email Main", 0, 0) - N(0x0512, "Contact Speed Dial Number", 0, 0) - N(0x0513, "Contact Status Flag", 0, 0) - N(0x0514, "Contact Misc.", 0, 0) - /* 0x0515-0xFFFF Reserved */ -#undef Y -#undef N -}; - int ucc_match(struct device *parent, void *match, void *aux) { @@ -642,7 +62,7 @@ ucc_match(struct device *parent, void *match, void *aux) uhidev_get_report_desc(uha->parent, &desc, &size); if (hid_report_size(desc, size, hid_input, uha->reportid) == 0) return UMATCH_NONE; - if (!ucc_hid_match(desc, size, uha->reportid)) + if (!hidcc_match(desc, size, uha->reportid)) return UMATCH_NONE; return UMATCH_IFACECLASS; @@ -654,10 +74,7 @@ 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; + int repid, size; sc->sc_hdev.sc_intr = ucc_intr; sc->sc_hdev.sc_parent = uha->parent; @@ -670,20 +87,17 @@ ucc_attach(struct device *parent, struct device *self, void *aux) 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_hid_parse(sc, desc, size); - if (error) { - printf(": hid error %d\n", error); - return; - } - - printf(": %d usage%s, %d key%s, %s\n", - sc->sc_nusages, sc->sc_nusages == 1 ? "" : "s", - sc->sc_maplen / 2, sc->sc_maplen / 2 == 1 ? "" : "s", - sc->sc_isarray ? "array" : "enum"); - - /* Cannot load an empty map. */ - if (sc->sc_maplen > 0) - ucc_attach_wskbd(sc, uha->uaa->cookie); + struct hidcc_attach_arg hca = { + .device = &sc->sc_hdev.sc_dev, + .audio_cookie = uha->uaa->cookie, + .desc = desc, + .descsiz = size, + .repid = repid, + .isize = sc->sc_hdev.sc_isize, + .enable = ucc_enable, + .arg = self, + }; + sc->sc_cc = hidcc_attach(&hca); } int @@ -692,12 +106,9 @@ 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_input.i_buf, M_USBDEV, sc->sc_input.i_bufsiz); - free(sc->sc_map, M_USBDEV, sc->sc_mapsiz * sizeof(*sc->sc_map)); - free(sc->sc_raw, M_USBDEV, sc->sc_rawsiz * sizeof(*sc->sc_raw)); + if (sc->sc_cc != NULL) + error = hidcc_detach(sc->sc_cc, flags); return error; } @@ -705,98 +116,9 @@ void ucc_intr(struct uhidev *addr, void *data, u_int len) { struct ucc_softc *sc = (struct ucc_softc *)addr; - const struct ucc_keysym *us; - uint8_t *buf = sc->sc_input.i_buf; - int raw = sc->sc_mode == WSKBD_RAW; - int error; - u_int bit = 0; - - ucc_dump(sc, __func__, data, len); - - if (len > sc->sc_input.i_bufsiz) { - DPRINTF("%s: too much data: len %d, bufsiz %d\n", DEVNAME(sc), - len, sc->sc_input.i_bufsiz); - return; - } - - error = ucc_intr_slice(sc, data, buf, &len); - if (error) { - DPRINTF("%s: slice failure: error %d\n", DEVNAME(sc), error); - return; - } - - /* Dump the buffer again after slicing. */ - ucc_dump(sc, __func__, buf, len); - - if (ucc_setbits(sc, buf, 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; - } else if (sc->sc_isarray) { - int32_t usage; - if (ucc_bits_to_int(buf, len, &usage) || - ucc_usage_to_sym(usage, &us)) - goto unknown; - bit = us->us_usage; - } else if (raw) { - if (ucc_bit_to_sym(sc, bit, &us)) - goto unknown; - } - - if (raw) { - ucc_rawinput(sc, us->us_raw, 0); - sc->sc_last_raw = us->us_raw; - /* - * Feed both raw and translating input for keys that have both - * defined. This is only the case for volume related keys. - */ - if (us->us_key == 0) - return; - } - - ucc_input(sc, bit, 0); - if (!raw) - sc->sc_last_translate = bit; - return; - -unknown: - DPRINTF("%s: unknown key: bit %d\n", DEVNAME(sc), bit); -} - -void -ucc_attach_wskbd(struct ucc_softc *sc, void *cookie) -{ - 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, - .audiocookie = NULL, /* XXX cookie */ - }; - - 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_NOENCODING; - sc->sc_wskbddev = config_found(&sc->sc_hdev.sc_dev, &a, wskbddevprint); + if (sc->sc_cc != NULL) + hidcc_intr(sc->sc_cc, data, len); } int @@ -811,438 +133,3 @@ ucc_enable(void *v, int on) 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) -{ - switch (cmd) { - /* wsconsctl(8) stub */ - case WSKBDIO_GTYPE: - *(int *)data = WSKBD_TYPE_USB; - return 0; - - /* wsconsctl(8) stub */ - case WSKBDIO_GETLEDS: - *(int *)data = 0; - return 0; - -#ifdef WSDISPLAY_COMPAT_RAWKBD - case WSKBDIO_SETMODE: { - struct ucc_softc *sc = (struct ucc_softc *)v; - - sc->sc_mode = *(int *)data; - return 0; - } -#endif - } - - return -1; -} - -/* - * Returns non-zero if the given report ID has at least one Consumer Control - * usage. - */ -int -ucc_hid_match(void *desc, int descsiz, uint8_t repid) -{ - struct hid_item hi; - struct hid_data *hd; - int32_t maxusage = 0; - - hd = hid_start_parse(desc, descsiz, hid_input); - while (hid_get_item(hd, &hi)) { - if (hi.report_ID == repid && - hi.kind == hid_input && - HID_GET_USAGE_PAGE(hi.usage) == HUP_CONSUMER) { - if (HID_GET_USAGE(hi.usage_maximum) > maxusage) - maxusage = HID_GET_USAGE(hi.usage_maximum); - else if (HID_GET_USAGE(hi.usage) > maxusage) - maxusage = HID_GET_USAGE(hi.usage); - } - } - hid_end_parse(hd); - return maxusage > 0; -} - -/* - * Parse the HID report and construct a mapping between the bits in the input - * report and the corresponding pressed key. - */ -int -ucc_hid_parse(struct ucc_softc *sc, void *desc, int descsiz) -{ - enum { OFFSET, LENGTH } istate = OFFSET; - struct hid_item hi; - struct hid_data *hd; - u_int bit = 0; - int error = 0; - int nsyms = nitems(ucc_keysyms); - int repid = sc->sc_hdev.sc_report_id; - 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; - - /* Allocate buffer used to slice interrupt data. */ - sc->sc_input.i_bufsiz = sc->sc_hdev.sc_isize; - sc->sc_input.i_buf = malloc(sc->sc_input.i_bufsiz, M_USBDEV, M_WAITOK); - - /* - * Create mapping between each input bit and the corresponding usage, - * used in translating mode. Two entries are needed per bit in order - * construct a mapping. Note that at most all known usages as given by - * ucc_keysyms can be inserted into this map. - */ - sc->sc_mapsiz = nsyms * 2; - sc->sc_map = mallocarray(nsyms, 2 * sizeof(*sc->sc_map), M_USBDEV, - M_WAITOK | M_ZERO); - - /* - * Create mapping between each input bit and the corresponding usage, - * used in raw mode. - */ - sc->sc_rawsiz = isize; - 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)) { - uint32_t off; - int32_t usage; - - if (hi.report_ID != repid || hi.kind != hid_input) - continue; - - if (HID_GET_USAGE_PAGE(hi.usage) != HUP_CONSUMER) { - uint32_t len = hi.loc.size * hi.loc.count; - - switch (istate) { - case OFFSET: - sc->sc_input.i_off = hi.loc.pos + len; - break; - case LENGTH: - /* Constant padding. */ - if (hi.flags & HIO_CONST) - sc->sc_input.i_len += len; - break; - } - continue; - } - - /* Signal that the input offset is reached. */ - istate = LENGTH; - off = sc->sc_input.i_len; - sc->sc_input.i_len += hi.loc.size * hi.loc.count; - - /* - * The usages could be expressed as an array instead of - * enumerating all supported ones. - */ - if (ucc_hid_is_array(&hi)) { - error = ucc_hid_parse_array(sc, &hi); - break; - } - - usage = HID_GET_USAGE(hi.usage); - if (usage == HUC_VOLUME) - error = ucc_add_key_volume(sc, &hi, off, bit); - else - error = ucc_add_key(sc, usage, bit); - if (error) - break; - sc->sc_nusages++; - bit += hi.loc.size * hi.loc.count; - } - hid_end_parse(hd); - - DPRINTF("%s: input: off %d, len %d\n", DEVNAME(sc), - sc->sc_input.i_off, sc->sc_input.i_len); - - return error; -} - -int -ucc_hid_parse_array(struct ucc_softc *sc, const struct hid_item *hi) -{ - int32_t max, min, usage; - - min = HID_GET_USAGE(hi->usage_minimum); - max = HID_GET_USAGE(hi->usage_maximum); - - sc->sc_nusages = (max - min) + 1; - sc->sc_isarray = 1; - - for (usage = min; usage <= max; usage++) { - int error; - - error = ucc_add_key(sc, usage, 0); - if (error) - return error; - } - - return 0; -} - -int -ucc_hid_is_array(const struct hid_item *hi) -{ - int32_t max, min; - - min = HID_GET_USAGE(hi->usage_minimum); - max = HID_GET_USAGE(hi->usage_maximum); - return min >= 0 && max > 0 && min < max; -} - -int -ucc_add_key(struct ucc_softc *sc, int32_t usage, u_int bit) -{ - const struct ucc_keysym *us; - - if (ucc_usage_to_sym(usage, &us)) - return 0; - - if (sc->sc_maplen + 2 > sc->sc_mapsiz) - return ENOMEM; - sc->sc_map[sc->sc_maplen++] = KS_KEYCODE(sc->sc_isarray ? usage : bit); - sc->sc_map[sc->sc_maplen++] = us->us_key; - - if (!sc->sc_isarray) { - if (bit >= sc->sc_rawsiz) - return ENOMEM; - sc->sc_raw[bit] = us; - } - - DPRINTF("%s: bit %d, usage \"%s\"\n", DEVNAME(sc), - bit, us->us_name); - return 0; -} - -/* - * Add key mappings for the volume usage which differs compared to the volume - * increment/decrement usages in which each volume change direction is - * represented using a distinct usage. The volume usage instead uses bits of the - * interrupt buffer to represent the wanted volume. The same bits should be - * within the bounds given by the logical min/max associated with the HID item. - */ -int -ucc_add_key_volume(struct ucc_softc *sc, const struct hid_item *hi, - uint32_t off, u_int bit) -{ - uint32_t len; - int error; - - /* - * Since the volume usage is internally represented using two key - * mappings, make sure enough bits are available to avoid any ambiguity. - */ - len = hi->loc.size * hi->loc.count; - if (len <= 1) - return 1; - - sc->sc_volume.v_inc = bit; - sc->sc_volume.v_dec = bit + 1; - sc->sc_volume.v_off = off; - sc->sc_volume.v_len = len; - - DPRINTF("%s: inc %d, dec %d, off %d, len %d, min %d, max %d\n", - DEVNAME(sc), sc->sc_volume.v_inc, sc->sc_volume.v_dec, - sc->sc_volume.v_off, sc->sc_volume.v_len, - hi->logical_minimum, hi->logical_maximum); - - error = ucc_add_key(sc, HUC_VOL_INC, sc->sc_volume.v_inc); - if (error) - return error; - error = ucc_add_key(sc, HUC_VOL_DEC, sc->sc_volume.v_dec); - if (error) - return error; - return 0; -} - -int -ucc_bit_to_sym(struct ucc_softc *sc, u_int bit, const struct ucc_keysym **us) -{ - if (bit >= sc->sc_rawsiz || sc->sc_raw[bit] == NULL) - return 1; - *us = sc->sc_raw[bit]; - return 0; -} - -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; -} - -int -ucc_bits_to_int(uint8_t *buf, u_int buflen, int32_t *usage) -{ - int32_t x = 0; - int i; - - if (buflen == 0 || buflen > sizeof(*usage)) - return 1; - - for (i = buflen - 1; i >= 0; i--) { - x |= buf[i]; - if (i > 0) - x <<= 8; - } - *usage = x; - return 0; -} - -int -ucc_bits_to_volume(struct ucc_softc *sc, uint8_t *buf, int buflen, u_int *bit) -{ - uint32_t vlen = sc->sc_volume.v_len; - uint32_t voff = sc->sc_volume.v_off; - int32_t vol; - int sign; - - if (vlen == 0) - return 1; - if (ucc_bits_to_int(buf, buflen, &vol)) - return 1; - vol = (vol >> voff) & ((1 << vlen) - 1); - if (vol == 0) - return 1; - - /* - * Interpret the volume as a relative change by only looking at the sign - * in order to determine the change direction. - */ - sign = vol & (1 << (vlen - 1)) ? -1 : 1; - if (sign < 0) - vol = (1 << vlen) - vol; - vol *= sign; - if (vol > 0) - *bit = sc->sc_volume.v_inc; - else - *bit = sc->sc_volume.v_dec; - return 0; -} - -int -ucc_intr_slice(struct ucc_softc *sc, uint8_t *src, uint8_t *dst, int *len) -{ - int ilen = sc->sc_input.i_len; - int ioff = sc->sc_input.i_off; - int maxlen = *len; - int di, si; - - if (maxlen == 0) - return 1; - - memset(dst, 0, maxlen); - si = ioff; - di = 0; - for (; ilen > 0; ilen--) { - int db, sb; - - sb = si / 8; - db = di / 8; - if (sb >= maxlen || db >= maxlen) - return 1; - - if (src[sb] & (1 << (si % 8))) - dst[db] |= 1 << (di % 8); - si++; - di++; - } - - *len = (sc->sc_input.i_len + 7) / 8; - return 0; -} - -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) -{ -#ifdef WSDISPLAY_COMPAT_RAWKBD - 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); -#endif -} - -int -ucc_setbits(struct ucc_softc *sc, uint8_t *data, int len, u_int *bit) -{ - int i, j; - - if (ucc_bits_to_volume(sc, data, len, bit) == 0) - return 0; - - 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(struct ucc_softc *sc, const char *prefix, uint8_t *data, u_int len) -{ - u_int i; - - if (ucc_debug == 0) - return; - - printf("%s: %s:", DEVNAME(sc), prefix); - for (i = 0; i < len; i++) - printf(" %02x", data[i]); - printf("\n"); -} - -#endif -- 2.20.1