xref: /freebsd/sys/dev/hid/hcons.c (revision 7eeede158604048dd21c5817bf9d9ee4721a9129)
1afd590d9SVladimir Kondratyev /*-
2afd590d9SVladimir Kondratyev  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3afd590d9SVladimir Kondratyev  *
4afd590d9SVladimir Kondratyev  * Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
5afd590d9SVladimir Kondratyev  *
6afd590d9SVladimir Kondratyev  * Redistribution and use in source and binary forms, with or without
7afd590d9SVladimir Kondratyev  * modification, are permitted provided that the following conditions
8afd590d9SVladimir Kondratyev  * are met:
9afd590d9SVladimir Kondratyev  * 1. Redistributions of source code must retain the above copyright
10afd590d9SVladimir Kondratyev  *    notice, this list of conditions and the following disclaimer.
11afd590d9SVladimir Kondratyev  * 2. Redistributions in binary form must reproduce the above copyright
12afd590d9SVladimir Kondratyev  *    notice, this list of conditions and the following disclaimer in the
13afd590d9SVladimir Kondratyev  *    documentation and/or other materials provided with the distribution.
14afd590d9SVladimir Kondratyev  *
15afd590d9SVladimir Kondratyev  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16afd590d9SVladimir Kondratyev  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17afd590d9SVladimir Kondratyev  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18afd590d9SVladimir Kondratyev  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19afd590d9SVladimir Kondratyev  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20afd590d9SVladimir Kondratyev  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21afd590d9SVladimir Kondratyev  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22afd590d9SVladimir Kondratyev  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23afd590d9SVladimir Kondratyev  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24afd590d9SVladimir Kondratyev  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25afd590d9SVladimir Kondratyev  * SUCH DAMAGE.
26afd590d9SVladimir Kondratyev  */
27afd590d9SVladimir Kondratyev 
28afd590d9SVladimir Kondratyev #include <sys/cdefs.h>
29afd590d9SVladimir Kondratyev __FBSDID("$FreeBSD$");
30afd590d9SVladimir Kondratyev 
31afd590d9SVladimir Kondratyev /*
32afd590d9SVladimir Kondratyev  * Consumer Controls usage page driver
33afd590d9SVladimir Kondratyev  * https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
34afd590d9SVladimir Kondratyev  */
35afd590d9SVladimir Kondratyev 
36afd590d9SVladimir Kondratyev #include <sys/param.h>
37afd590d9SVladimir Kondratyev #include <sys/bitstring.h>
38afd590d9SVladimir Kondratyev #include <sys/bus.h>
39afd590d9SVladimir Kondratyev #include <sys/kernel.h>
40afd590d9SVladimir Kondratyev #include <sys/module.h>
41afd590d9SVladimir Kondratyev #include <sys/sysctl.h>
42afd590d9SVladimir Kondratyev 
43afd590d9SVladimir Kondratyev #include <dev/evdev/input.h>
44afd590d9SVladimir Kondratyev #include <dev/evdev/evdev.h>
45afd590d9SVladimir Kondratyev 
46afd590d9SVladimir Kondratyev #include <dev/hid/hid.h>
47afd590d9SVladimir Kondratyev #include <dev/hid/hidbus.h>
48afd590d9SVladimir Kondratyev #include <dev/hid/hidmap.h>
49afd590d9SVladimir Kondratyev 
50afd590d9SVladimir Kondratyev static hidmap_cb_t	hcons_rel_volume_cb;
51afd590d9SVladimir Kondratyev 
52afd590d9SVladimir Kondratyev #define	HCONS_MAP_KEY(usage, code)	\
53afd590d9SVladimir Kondratyev 	{ HIDMAP_KEY(HUP_CONSUMER, usage, code) }
54afd590d9SVladimir Kondratyev #define	HCONS_MAP_ABS(usage, code)	\
55afd590d9SVladimir Kondratyev 	{ HIDMAP_ABS(HUP_CONSUMER, usage, code) }
56afd590d9SVladimir Kondratyev #define	HCONS_MAP_REL(usage, code)	\
57afd590d9SVladimir Kondratyev 	{ HIDMAP_REL(HUP_CONSUMER, usage, code) }
58afd590d9SVladimir Kondratyev #define HCONS_MAP_REL_CB(usage, callback)	\
59afd590d9SVladimir Kondratyev 	{ HIDMAP_REL_CB(HUP_CONSUMER, usage, &callback) }
60afd590d9SVladimir Kondratyev 
61afd590d9SVladimir Kondratyev static const struct hidmap_item hcons_map[] = {
62afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x030,	KEY_POWER),
63afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x031,	KEY_RESTART),
64afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x032,	KEY_SLEEP),
65afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x034,	KEY_SLEEP),
66afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x035,	KEY_KBDILLUMTOGGLE),
67afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x036,	BTN_MISC),
68afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x040,	KEY_MENU),	/* Menu */
69afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x041,	KEY_SELECT),	/* Menu Pick */
70afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x042,	KEY_UP),	/* Menu Up */
71afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x043,	KEY_DOWN),	/* Menu Down */
72afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x044,	KEY_LEFT),	/* Menu Left */
73afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x045,	KEY_RIGHT),	/* Menu Right */
74afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x046,	KEY_ESC),	/* Menu Escape */
75afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x047,	KEY_KPPLUS),	/* Menu Value Increase */
76afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x048,	KEY_KPMINUS),	/* Menu Value Decrease */
77afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x060,	KEY_INFO),	/* Data On Screen */
78afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x061,	KEY_SUBTITLE),	/* Closed Caption */
79afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x063,	KEY_VCR),	/* VCR/TV */
80afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x065,	KEY_CAMERA),	/* Snapshot */
81afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x069,	KEY_RED),
82afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x06a,	KEY_GREEN),
83afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x06b,	KEY_BLUE),
84afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x06c,	KEY_YELLOW),
85afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x06d,	KEY_ASPECT_RATIO),
86afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x06f,	KEY_BRIGHTNESSUP),
87afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x070,	KEY_BRIGHTNESSDOWN),
88afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x072,	KEY_BRIGHTNESS_TOGGLE),
89afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x073,	KEY_BRIGHTNESS_MIN),
90afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x074,	KEY_BRIGHTNESS_MAX),
91afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x075,	KEY_BRIGHTNESS_AUTO),
92afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x079,	KEY_KBDILLUMUP),
93afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x07a,	KEY_KBDILLUMDOWN),
94afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x07c,	KEY_KBDILLUMTOGGLE),
95afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x082,	KEY_VIDEO_NEXT),
96afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x083,	KEY_LAST),
97afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x084,	KEY_ENTER),
98afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x088,	KEY_PC),
99afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x089,	KEY_TV),
100afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x08a,	KEY_WWW),
101afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x08b,	KEY_DVD),
102afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x08c,	KEY_PHONE),
103afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x08d,	KEY_PROGRAM),
104afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x08e,	KEY_VIDEOPHONE),
105afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x08f,	KEY_GAMES),
106afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x090,	KEY_MEMO),
107afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x091,	KEY_CD),
108afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x092,	KEY_VCR),
109afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x093,	KEY_TUNER),
110afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x094,	KEY_EXIT),
111afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x095,	KEY_HELP),
112afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x096,	KEY_TAPE),
113afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x097,	KEY_TV2),
114afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x098,	KEY_SAT),
115afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x09a,	KEY_PVR),
116afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x09c,	KEY_CHANNELUP),
117afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x09d,	KEY_CHANNELDOWN),
118afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0a0,	KEY_VCR2),
119afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0b0,	KEY_PLAY),
120afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0b1,	KEY_PAUSE),
121afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0b2,	KEY_RECORD),
122afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0b3,	KEY_FASTFORWARD),
123afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0b4,	KEY_REWIND),
124afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0b5,	KEY_NEXTSONG),
125afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0b6,	KEY_PREVIOUSSONG),
126afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0b7,	KEY_STOPCD),
127afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0b8,	KEY_EJECTCD),
128afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0bc,	KEY_MEDIA_REPEAT),
129afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0b9,	KEY_SHUFFLE),
130afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0bf,	KEY_SLOW),
131afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0cd,	KEY_PLAYPAUSE),
132afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0cf,	KEY_VOICECOMMAND),
133afd590d9SVladimir Kondratyev 	HCONS_MAP_ABS(0x0e0,	ABS_VOLUME),
134afd590d9SVladimir Kondratyev 	HCONS_MAP_REL_CB(0x0e0,	hcons_rel_volume_cb),
135afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0e2,	KEY_MUTE),
136afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0e5,	KEY_BASSBOOST),
137afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0e9,	KEY_VOLUMEUP),
138afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0ea,	KEY_VOLUMEDOWN),
139afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x0f5,	KEY_SLOW),
140afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x181,	KEY_BUTTONCONFIG),
141afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x182,	KEY_BOOKMARKS),
142afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x183,	KEY_CONFIG),
143afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x184,	KEY_WORDPROCESSOR),
144afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x185,	KEY_EDITOR),
145afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x186,	KEY_SPREADSHEET),
146afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x187,	KEY_GRAPHICSEDITOR),
147afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x188,	KEY_PRESENTATION),
148afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x189,	KEY_DATABASE),
149afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x18a,	KEY_MAIL),
150afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x18b,	KEY_NEWS),
151afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x18c,	KEY_VOICEMAIL),
152afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x18d,	KEY_ADDRESSBOOK),
153afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x18e,	KEY_CALENDAR),
154afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x18f,	KEY_TASKMANAGER),
155afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x190,	KEY_JOURNAL),
156afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x191,	KEY_FINANCE),
157afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x192,	KEY_CALC),
158afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x193,	KEY_PLAYER),
159afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x194,	KEY_FILE),
160afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x196,	KEY_WWW),
161afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x199,	KEY_CHAT),
162afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x19c,	KEY_LOGOFF),
163afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x19e,	KEY_COFFEE),
164afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x19f,	KEY_CONTROLPANEL),
165afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1a2,	KEY_APPSELECT),
166afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1a3,	KEY_NEXT),
167afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1a4,	KEY_PREVIOUS),
168afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1a6,	KEY_HELP),
169afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1a7,	KEY_DOCUMENTS),
170afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1ab,	KEY_SPELLCHECK),
171afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1ae,	KEY_KEYBOARD),
172afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1b1,	KEY_SCREENSAVER),
173afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1b4,	KEY_FILE),
174afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1b6,	KEY_IMAGES),
175afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1b7,	KEY_AUDIO),
176afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1b8,	KEY_VIDEO),
177afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1bc,	KEY_MESSENGER),
178afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1bd,	KEY_INFO),
179afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x1cb,	KEY_ASSISTANT),
180afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x201,	KEY_NEW),
181afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x202,	KEY_OPEN),
182afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x203,	KEY_CLOSE),
183afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x204,	KEY_EXIT),
184afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x207,	KEY_SAVE),
185afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x208,	KEY_PRINT),
186afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x209,	KEY_PROPS),
187afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x21a,	KEY_UNDO),
188afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x21b,	KEY_COPY),
189afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x21c,	KEY_CUT),
190afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x21d,	KEY_PASTE),
191afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x21f,	KEY_FIND),
192afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x221,	KEY_SEARCH),
193afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x222,	KEY_GOTO),
194afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x223,	KEY_HOMEPAGE),
195afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x224,	KEY_BACK),
196afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x225,	KEY_FORWARD),
197afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x226,	KEY_STOP),
198afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x227,	KEY_REFRESH),
199afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x22a,	KEY_BOOKMARKS),
200afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x22d,	KEY_ZOOMIN),
201afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x22e,	KEY_ZOOMOUT),
202afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x22f,	KEY_ZOOMRESET),
203afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x232,	KEY_FULL_SCREEN),
204afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x233,	KEY_SCROLLUP),
205afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x234,	KEY_SCROLLDOWN),
206afd590d9SVladimir Kondratyev 	HCONS_MAP_REL(0x238,	REL_HWHEEL),	 /* AC Pan */
207afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x23d,	KEY_EDIT),
208afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x25f,	KEY_CANCEL),
209afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x269,	KEY_INSERT),
210afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x26a,	KEY_DELETE),
211afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x279,	KEY_REDO),
212afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x289,	KEY_REPLY),
213afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x28b,	KEY_FORWARDMAIL),
214afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x28c,	KEY_SEND),
215afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x29d,	KEY_KBD_LAYOUT_NEXT),
216afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x2c7,	KEY_KBDINPUTASSIST_PREV),
217afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x2c8,	KEY_KBDINPUTASSIST_NEXT),
218afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x2c9,	KEY_KBDINPUTASSIST_PREVGROUP),
219afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x2ca,	KEY_KBDINPUTASSIST_NEXTGROUP),
220afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x2cb,	KEY_KBDINPUTASSIST_ACCEPT),
221afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x2cc,	KEY_KBDINPUTASSIST_CANCEL),
222afd590d9SVladimir Kondratyev 	HCONS_MAP_KEY(0x29f,	KEY_SCALE),
223afd590d9SVladimir Kondratyev };
224afd590d9SVladimir Kondratyev 
225afd590d9SVladimir Kondratyev static const struct hid_device_id hcons_devs[] = {
226afd590d9SVladimir Kondratyev 	{ HID_TLC(HUP_CONSUMER, HUC_CONTROL) },
227afd590d9SVladimir Kondratyev };
228afd590d9SVladimir Kondratyev 
229afd590d9SVladimir Kondratyev /*
230afd590d9SVladimir Kondratyev  * Emulate relative Consumer volume usage with pressing
231afd590d9SVladimir Kondratyev  * VOLUMEUP and VOLUMEDOWN keys appropriate number of times
232afd590d9SVladimir Kondratyev  */
233afd590d9SVladimir Kondratyev static int
234afd590d9SVladimir Kondratyev hcons_rel_volume_cb(HIDMAP_CB_ARGS)
235afd590d9SVladimir Kondratyev {
236afd590d9SVladimir Kondratyev 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
237afd590d9SVladimir Kondratyev 	int32_t code;
238afd590d9SVladimir Kondratyev 	int nrepeats;
239afd590d9SVladimir Kondratyev 
240afd590d9SVladimir Kondratyev 	switch (HIDMAP_CB_GET_STATE()) {
241afd590d9SVladimir Kondratyev 	case HIDMAP_CB_IS_ATTACHING:
242afd590d9SVladimir Kondratyev 		evdev_support_event(evdev, EV_KEY);
243afd590d9SVladimir Kondratyev 		evdev_support_key(evdev, KEY_VOLUMEUP);
244afd590d9SVladimir Kondratyev 		evdev_support_key(evdev, KEY_VOLUMEDOWN);
245afd590d9SVladimir Kondratyev 		break;
246afd590d9SVladimir Kondratyev 	case HIDMAP_CB_IS_RUNNING:
247afd590d9SVladimir Kondratyev 		/* Nothing to report. */
248afd590d9SVladimir Kondratyev 		if (ctx.data == 0)
249afd590d9SVladimir Kondratyev 			return (ENOMSG);
250afd590d9SVladimir Kondratyev 		code = ctx.data > 0 ? KEY_VOLUMEUP : KEY_VOLUMEDOWN;
251afd590d9SVladimir Kondratyev 		for (nrepeats = abs(ctx.data); nrepeats > 0; nrepeats--) {
252afd590d9SVladimir Kondratyev 			evdev_push_key(evdev, code, 1);
253afd590d9SVladimir Kondratyev 			evdev_push_key(evdev, code, 0);
254afd590d9SVladimir Kondratyev 		}
25516079c72SRyan Libby 		break;
25616079c72SRyan Libby 	default:
25716079c72SRyan Libby 		break;
258afd590d9SVladimir Kondratyev 	}
259afd590d9SVladimir Kondratyev 
260afd590d9SVladimir Kondratyev 	return (0);
261afd590d9SVladimir Kondratyev }
262afd590d9SVladimir Kondratyev 
263afd590d9SVladimir Kondratyev static int
264afd590d9SVladimir Kondratyev hcons_probe(device_t dev)
265afd590d9SVladimir Kondratyev {
266afd590d9SVladimir Kondratyev 	return (HIDMAP_PROBE(device_get_softc(dev), dev,
267afd590d9SVladimir Kondratyev 	    hcons_devs, hcons_map, "Consumer Control"));
268afd590d9SVladimir Kondratyev }
269afd590d9SVladimir Kondratyev 
270afd590d9SVladimir Kondratyev static int
271afd590d9SVladimir Kondratyev hcons_attach(device_t dev)
272afd590d9SVladimir Kondratyev {
273afd590d9SVladimir Kondratyev 	return (hidmap_attach(device_get_softc(dev)));
274afd590d9SVladimir Kondratyev }
275afd590d9SVladimir Kondratyev 
276afd590d9SVladimir Kondratyev static int
277afd590d9SVladimir Kondratyev hcons_detach(device_t dev)
278afd590d9SVladimir Kondratyev {
279afd590d9SVladimir Kondratyev 	return (hidmap_detach(device_get_softc(dev)));
280afd590d9SVladimir Kondratyev }
281afd590d9SVladimir Kondratyev 
282afd590d9SVladimir Kondratyev static device_method_t hcons_methods[] = {
283afd590d9SVladimir Kondratyev 	DEVMETHOD(device_probe,		hcons_probe),
284afd590d9SVladimir Kondratyev 	DEVMETHOD(device_attach,	hcons_attach),
285afd590d9SVladimir Kondratyev 	DEVMETHOD(device_detach,	hcons_detach),
286afd590d9SVladimir Kondratyev 
287afd590d9SVladimir Kondratyev 	DEVMETHOD_END
288afd590d9SVladimir Kondratyev };
289afd590d9SVladimir Kondratyev 
290afd590d9SVladimir Kondratyev DEFINE_CLASS_0(hcons, hcons_driver, hcons_methods, sizeof(struct hidmap));
291*7eeede15SJohn Baldwin DRIVER_MODULE(hcons, hidbus, hcons_driver, NULL, NULL);
292afd590d9SVladimir Kondratyev MODULE_DEPEND(hcons, hid, 1, 1, 1);
293afd590d9SVladimir Kondratyev MODULE_DEPEND(hcons, hidbus, 1, 1, 1);
294afd590d9SVladimir Kondratyev MODULE_DEPEND(hcons, hidmap, 1, 1, 1);
295afd590d9SVladimir Kondratyev MODULE_DEPEND(hcons, evdev, 1, 1, 1);
296afd590d9SVladimir Kondratyev MODULE_VERSION(hcons, 1);
297afd590d9SVladimir Kondratyev HID_PNP_INFO(hcons_devs);
298