-/* $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 <anton@openbsd.org>
#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 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 <dev/hid/hidccvar.h>
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 *);
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
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)
{
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;
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;
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
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;
}
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
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