xref: /onnv-gate/usr/src/uts/common/io/kbtrans/kbtrans_polled.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * Generic Keyboard Support: Polled I/O support for kbtrans-supported keyboards.
31*0Sstevel@tonic-gate  */
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #define	KEYMAP_SIZE_VARIABLE
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #include <sys/types.h>
36*0Sstevel@tonic-gate #include <sys/stream.h>
37*0Sstevel@tonic-gate #include <sys/kbd.h>
38*0Sstevel@tonic-gate #include <sys/kbio.h>
39*0Sstevel@tonic-gate #include <sys/vuid_event.h>
40*0Sstevel@tonic-gate #include <sys/consdev.h>
41*0Sstevel@tonic-gate #include <sys/kbtrans.h>
42*0Sstevel@tonic-gate #include "kbtrans_lower.h"
43*0Sstevel@tonic-gate #include "kbtrans_streams.h"
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate /*
46*0Sstevel@tonic-gate  * Internal Function Prototypes
47*0Sstevel@tonic-gate  */
48*0Sstevel@tonic-gate static void kbtrans_polled_pressed(struct kbtrans *, uint_t, kbtrans_key_t,
49*0Sstevel@tonic-gate 			uint_t);
50*0Sstevel@tonic-gate static void kbtrans_polled_released(struct kbtrans *, kbtrans_key_t);
51*0Sstevel@tonic-gate static void kbtrans_polled_setled(struct kbtrans *);
52*0Sstevel@tonic-gate static void kbtrans_polled_setup_repeat(struct kbtrans *, uint_t,
53*0Sstevel@tonic-gate 			kbtrans_key_t);
54*0Sstevel@tonic-gate static void kbtrans_polled_cancel_repeat(struct kbtrans *);
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate /*
57*0Sstevel@tonic-gate  * Functions to be called when a key is translated during polled
58*0Sstevel@tonic-gate  * mode
59*0Sstevel@tonic-gate  */
60*0Sstevel@tonic-gate struct keyboard_callback kbtrans_polled_callbacks = {
61*0Sstevel@tonic-gate 	NULL,				/* keypressed_raw */
62*0Sstevel@tonic-gate 	NULL,				/* keyreleased_raw */
63*0Sstevel@tonic-gate 	kbtrans_polled_pressed,		/* keypressed */
64*0Sstevel@tonic-gate 	kbtrans_polled_released,	/* keyreleased */
65*0Sstevel@tonic-gate 	kbtrans_polled_setup_repeat,	/* setup_repeat */
66*0Sstevel@tonic-gate 	kbtrans_polled_cancel_repeat,	/* cancel_repeat */
67*0Sstevel@tonic-gate 	kbtrans_polled_setled,		/* setled */
68*0Sstevel@tonic-gate };
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate /*
71*0Sstevel@tonic-gate  * kbtrans_ischar:
72*0Sstevel@tonic-gate  *	Return B_TRUE if character is pending, else return B_FALSE
73*0Sstevel@tonic-gate  */
74*0Sstevel@tonic-gate boolean_t
kbtrans_ischar(struct kbtrans * upper)75*0Sstevel@tonic-gate kbtrans_ischar(struct kbtrans *upper)
76*0Sstevel@tonic-gate {
77*0Sstevel@tonic-gate 	struct kbtrans_callbacks *cb;
78*0Sstevel@tonic-gate 	struct kbtrans_hardware *hw;
79*0Sstevel@tonic-gate 	kbtrans_key_t key;
80*0Sstevel@tonic-gate 	enum keystate state;
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate 	/*
83*0Sstevel@tonic-gate 	 * If we've still got input pending, say so.
84*0Sstevel@tonic-gate 	 */
85*0Sstevel@tonic-gate 	if (*upper->kbtrans_polled_pending_chars != '\0') {
86*0Sstevel@tonic-gate 		return (B_TRUE);
87*0Sstevel@tonic-gate 	}
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate 	/*
90*0Sstevel@tonic-gate 	 * Reset to an empty buffer.
91*0Sstevel@tonic-gate 	 */
92*0Sstevel@tonic-gate 	upper->kbtrans_polled_buf[0] = '\0';
93*0Sstevel@tonic-gate 	upper->kbtrans_polled_pending_chars = upper->kbtrans_polled_buf;
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate 	cb = upper->kbtrans_streams_hw_callbacks;
96*0Sstevel@tonic-gate 	hw = upper->kbtrans_streams_hw;
97*0Sstevel@tonic-gate 
98*0Sstevel@tonic-gate 	/*
99*0Sstevel@tonic-gate 	 * Process scancodes until either we have input ready
100*0Sstevel@tonic-gate 	 * or we run out of scancodes.
101*0Sstevel@tonic-gate 	 */
102*0Sstevel@tonic-gate 	while (cb->kbtrans_polled_keycheck(hw, &key, &state)) {
103*0Sstevel@tonic-gate 		kbtrans_processkey(&upper->kbtrans_lower,
104*0Sstevel@tonic-gate 			&kbtrans_polled_callbacks, key, state);
105*0Sstevel@tonic-gate 		/*
106*0Sstevel@tonic-gate 		 * If that generated any input, we're ready.
107*0Sstevel@tonic-gate 		 */
108*0Sstevel@tonic-gate 		if (*upper->kbtrans_polled_pending_chars != '\0') {
109*0Sstevel@tonic-gate 			return (B_TRUE);
110*0Sstevel@tonic-gate 		}
111*0Sstevel@tonic-gate 	}
112*0Sstevel@tonic-gate 
113*0Sstevel@tonic-gate 	return (B_FALSE);
114*0Sstevel@tonic-gate }
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate /*
117*0Sstevel@tonic-gate  * kbtrans_getchar:
118*0Sstevel@tonic-gate  * 	Return a character
119*0Sstevel@tonic-gate  */
120*0Sstevel@tonic-gate int
kbtrans_getchar(struct kbtrans * upper)121*0Sstevel@tonic-gate kbtrans_getchar(struct kbtrans *upper)
122*0Sstevel@tonic-gate {
123*0Sstevel@tonic-gate 	while (!kbtrans_ischar(upper))
124*0Sstevel@tonic-gate 		/* LOOP */;
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate 	return (*upper->kbtrans_polled_pending_chars++);
127*0Sstevel@tonic-gate }
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate void
kbtrans_polled_putcode(struct kbtrans * upper,char code)130*0Sstevel@tonic-gate kbtrans_polled_putcode(struct kbtrans *upper, char code)
131*0Sstevel@tonic-gate {
132*0Sstevel@tonic-gate 	int i;
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate 	/*
135*0Sstevel@tonic-gate 	 * NB:  KBTRANS_POLLED_BUF_SIZE is one smaller than
136*0Sstevel@tonic-gate 	 * the size of the buffer, to allow for a trailing
137*0Sstevel@tonic-gate 	 * null.
138*0Sstevel@tonic-gate 	 */
139*0Sstevel@tonic-gate 	for (i = 0; i < KBTRANS_POLLED_BUF_SIZE; i++) {
140*0Sstevel@tonic-gate 		if (upper->kbtrans_polled_buf[i] == '\0') {
141*0Sstevel@tonic-gate 			upper->kbtrans_polled_buf[i] = code;
142*0Sstevel@tonic-gate 			upper->kbtrans_polled_buf[i+1] = '\0';
143*0Sstevel@tonic-gate 			return;
144*0Sstevel@tonic-gate 		}
145*0Sstevel@tonic-gate 	}
146*0Sstevel@tonic-gate 	DPRINTF(PRINT_L2, PRINT_MASK_PACKET,
147*0Sstevel@tonic-gate 		(upper, "kbtrans_polled_pressed:  "
148*0Sstevel@tonic-gate 		"buffer overflow, character 0x%x discarded\n", code));
149*0Sstevel@tonic-gate 	/*
150*0Sstevel@tonic-gate 	 * Didn't fit, throw it on the floor.
151*0Sstevel@tonic-gate 	 */
152*0Sstevel@tonic-gate }
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate /*
155*0Sstevel@tonic-gate  * kbtrans_polled_pressed:
156*0Sstevel@tonic-gate  *	This function is called when we are in polled mode and a key is
157*0Sstevel@tonic-gate  * 	pressed.  The key is put into the kbtrans_polled_buf so that it
158*0Sstevel@tonic-gate  * 	can be picked up later by kbtrans_ischar()
159*0Sstevel@tonic-gate  */
160*0Sstevel@tonic-gate /*ARGSUSED2*/
161*0Sstevel@tonic-gate static void
kbtrans_polled_pressed(struct kbtrans * upper,uint_t entrytype,kbtrans_key_t key,uint_t entry)162*0Sstevel@tonic-gate kbtrans_polled_pressed(
163*0Sstevel@tonic-gate     struct kbtrans *upper,
164*0Sstevel@tonic-gate     uint_t entrytype,
165*0Sstevel@tonic-gate     kbtrans_key_t key,
166*0Sstevel@tonic-gate     uint_t entry)
167*0Sstevel@tonic-gate {
168*0Sstevel@tonic-gate 	struct kbtrans_lower	*lower = &upper->kbtrans_lower;
169*0Sstevel@tonic-gate 	register char	*cp;
170*0Sstevel@tonic-gate 
171*0Sstevel@tonic-gate 	/*
172*0Sstevel@tonic-gate 	 * Based on the type of key, we may need to do some ASCII
173*0Sstevel@tonic-gate 	 * specific post processing.
174*0Sstevel@tonic-gate 	 */
175*0Sstevel@tonic-gate 	switch (entrytype) {
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate 	case BUCKYBITS:
178*0Sstevel@tonic-gate 	case SHIFTKEYS:
179*0Sstevel@tonic-gate 	case FUNNY:
180*0Sstevel@tonic-gate 		/*
181*0Sstevel@tonic-gate 		 * There is no ascii equivalent.  We will ignore these
182*0Sstevel@tonic-gate 		 * keys
183*0Sstevel@tonic-gate 		 */
184*0Sstevel@tonic-gate 		break;
185*0Sstevel@tonic-gate 
186*0Sstevel@tonic-gate 	case FUNCKEYS:
187*0Sstevel@tonic-gate 		/*
188*0Sstevel@tonic-gate 		 * These will no doubt only cause problems.  Ignore them.
189*0Sstevel@tonic-gate 		 */
190*0Sstevel@tonic-gate 
191*0Sstevel@tonic-gate 		break;
192*0Sstevel@tonic-gate 
193*0Sstevel@tonic-gate 	case STRING:
194*0Sstevel@tonic-gate 		/*
195*0Sstevel@tonic-gate 		 * These are the multi byte keys (Home, Up, Down ...)
196*0Sstevel@tonic-gate 		 */
197*0Sstevel@tonic-gate 		cp = &lower->kbtrans_keystringtab[entry & 0x0F][0];
198*0Sstevel@tonic-gate 
199*0Sstevel@tonic-gate 		/*
200*0Sstevel@tonic-gate 		 * Copy the string from the keystringtable, and send it
201*0Sstevel@tonic-gate 		 * upstream a character at a time.
202*0Sstevel@tonic-gate 		 */
203*0Sstevel@tonic-gate 		while (*cp != '\0') {
204*0Sstevel@tonic-gate 			kbtrans_polled_putcode(upper, *cp);
205*0Sstevel@tonic-gate 			cp++;
206*0Sstevel@tonic-gate 		}
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate 		return;
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate 	case PADKEYS:
211*0Sstevel@tonic-gate 		/*
212*0Sstevel@tonic-gate 		 * These are the keys on the keypad.  Look up the
213*0Sstevel@tonic-gate 		 * answer in the kb_numlock_table and send it upstream.
214*0Sstevel@tonic-gate 		 */
215*0Sstevel@tonic-gate 		kbtrans_polled_putcode(upper,
216*0Sstevel@tonic-gate 			lower->kbtrans_numlock_table[entry&0x1F]);
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate 		break;
219*0Sstevel@tonic-gate 
220*0Sstevel@tonic-gate 	case 0:	/* normal character */
221*0Sstevel@tonic-gate 	default:
222*0Sstevel@tonic-gate 		/*
223*0Sstevel@tonic-gate 		 * Send the byte upstream.
224*0Sstevel@tonic-gate 		 */
225*0Sstevel@tonic-gate 		kbtrans_polled_putcode(upper, (char)entry);
226*0Sstevel@tonic-gate 		break;
227*0Sstevel@tonic-gate 	}
228*0Sstevel@tonic-gate }
229*0Sstevel@tonic-gate 
230*0Sstevel@tonic-gate /*
231*0Sstevel@tonic-gate  * kbtrans_polled_released:
232*0Sstevel@tonic-gate  *	This function is called when a key is released.  Nothing is
233*0Sstevel@tonic-gate  * 	done.
234*0Sstevel@tonic-gate  */
235*0Sstevel@tonic-gate /*ARGSUSED*/
236*0Sstevel@tonic-gate static void
kbtrans_polled_released(struct kbtrans * upper,kbtrans_key_t key)237*0Sstevel@tonic-gate kbtrans_polled_released(struct kbtrans *upper, kbtrans_key_t key)
238*0Sstevel@tonic-gate {
239*0Sstevel@tonic-gate 	/* Nothing for now */
240*0Sstevel@tonic-gate }
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate /*
243*0Sstevel@tonic-gate  * kbtrans_polled_setled:
244*0Sstevel@tonic-gate  *	This function is called to set the LEDs.
245*0Sstevel@tonic-gate  */
246*0Sstevel@tonic-gate static void
kbtrans_polled_setled(struct kbtrans * upper)247*0Sstevel@tonic-gate kbtrans_polled_setled(struct kbtrans *upper)
248*0Sstevel@tonic-gate {
249*0Sstevel@tonic-gate 	struct kbtrans_callbacks *cb;
250*0Sstevel@tonic-gate 	struct kbtrans_hardware *hw;
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate 	cb = upper->kbtrans_streams_hw_callbacks;
253*0Sstevel@tonic-gate 	hw = upper->kbtrans_streams_hw;
254*0Sstevel@tonic-gate 
255*0Sstevel@tonic-gate 	cb->kbtrans_polled_setled(hw, upper->kbtrans_lower.kbtrans_led_state);
256*0Sstevel@tonic-gate }
257*0Sstevel@tonic-gate 
258*0Sstevel@tonic-gate /*
259*0Sstevel@tonic-gate  * kbtrans_polled_setup_repeat:
260*0Sstevel@tonic-gate  *	Function to be called in order to handle a repeating key.
261*0Sstevel@tonic-gate  *	Nothing is done.
262*0Sstevel@tonic-gate  */
263*0Sstevel@tonic-gate /*ARGSUSED*/
264*0Sstevel@tonic-gate static void
kbtrans_polled_setup_repeat(struct kbtrans * upper,uint_t entrytype,kbtrans_key_t key)265*0Sstevel@tonic-gate kbtrans_polled_setup_repeat(
266*0Sstevel@tonic-gate     struct kbtrans *upper,
267*0Sstevel@tonic-gate     uint_t entrytype,
268*0Sstevel@tonic-gate     kbtrans_key_t key)
269*0Sstevel@tonic-gate {
270*0Sstevel@tonic-gate 	/* Nothing for now */
271*0Sstevel@tonic-gate }
272*0Sstevel@tonic-gate 
273*0Sstevel@tonic-gate /*
274*0Sstevel@tonic-gate  * kbtrans_polled_cancel_repeat:
275*0Sstevel@tonic-gate  *	Function to be called to cancel a repeating key,
276*0Sstevel@tonic-gate  *	so that we don't end up with an autorepeating key
277*0Sstevel@tonic-gate  * 	on the stream because its release was handled by the
278*0Sstevel@tonic-gate  * 	polled code.
279*0Sstevel@tonic-gate  */
280*0Sstevel@tonic-gate static void
kbtrans_polled_cancel_repeat(struct kbtrans * upper)281*0Sstevel@tonic-gate kbtrans_polled_cancel_repeat(struct kbtrans *upper)
282*0Sstevel@tonic-gate {
283*0Sstevel@tonic-gate 	/*
284*0Sstevel@tonic-gate 	 * Streams code will time out and will discard the
285*0Sstevel@tonic-gate 	 * autorepeat.
286*0Sstevel@tonic-gate 	 */
287*0Sstevel@tonic-gate 	upper->kbtrans_lower.kbtrans_repeatkey = 0;
288*0Sstevel@tonic-gate }
289