FreeBSD/Linux Kernel Cross Reference
sys/dev/dec/lk201_ws.c
1 /* $NetBSD: lk201_ws.c,v 1.7 2005/12/11 12:21:20 christos Exp $ */
2
3 /*
4 * Copyright (c) 1998
5 * Matthias Drochner. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: lk201_ws.c,v 1.7 2005/12/11 12:21:20 christos Exp $");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34
35 #include <dev/wscons/wsconsio.h>
36
37 #include <dev/dec/lk201reg.h>
38 #include <dev/dec/lk201var.h>
39 #include <dev/dec/wskbdmap_lk201.h> /* for {MIN,MAX}_LK201_KEY */
40
41 #define send(lks, c) ((*((lks)->attmt.sendchar))((lks)->attmt.cookie, c))
42
43 int
44 lk201_init(lks)
45 struct lk201_state *lks;
46 {
47 int i;
48
49 send(lks, LK_LED_ENABLE);
50 send(lks, LK_LED_ALL);
51
52 /*
53 * set all keys to updown mode; autorepeat is
54 * done by wskbd software
55 */
56 for (i = 1; i <= 14; i++)
57 send(lks, LK_CMD_MODE(LK_UPDOWN, i));
58
59 send(lks, LK_CL_ENABLE);
60 send(lks, LK_PARAM_VOLUME(3));
61 lks->kcvol = (8 - 3) * 100 / 8;
62
63 lks->bellvol = -1; /* not yet set */
64
65 for (i = 0; i < LK_KLL; i++)
66 lks->down_keys_list[i] = -1;
67 send(lks, LK_KBD_ENABLE);
68
69 send(lks, LK_LED_DISABLE);
70 send(lks, LK_LED_ALL);
71 lks->leds_state = 0;
72
73 return (0);
74 }
75
76 int
77 lk201_decode(lks, datain, type, dataout)
78 struct lk201_state *lks;
79 int datain;
80 u_int *type;
81 int *dataout;
82 {
83 int i, freeslot;
84
85 switch (datain) {
86 case LK_KEY_UP:
87 for (i = 0; i < LK_KLL; i++)
88 lks->down_keys_list[i] = -1;
89 *type = WSCONS_EVENT_ALL_KEYS_UP;
90 return (1);
91 case LK_POWER_UP:
92 printf("lk201_decode: powerup detected\n");
93 lk201_init(lks);
94 return (0);
95 case LK_KDOWN_ERROR:
96 case LK_POWER_ERROR:
97 case LK_OUTPUT_ERROR:
98 case LK_INPUT_ERROR:
99 printf("lk201_decode: error %x\n", datain);
100 /* FALLTHRU */
101 case LK_KEY_REPEAT: /* autorepeat handled by wskbd */
102 case LK_MODE_CHANGE: /* ignore silently */
103 return (0);
104 }
105
106 if (datain < MIN_LK201_KEY || datain > MAX_LK201_KEY) {
107 printf("lk201_decode: %x\n", datain);
108 return (0);
109 }
110
111 *dataout = datain - MIN_LK201_KEY;
112
113 freeslot = -1;
114 for (i = 0; i < LK_KLL; i++) {
115 if (lks->down_keys_list[i] == datain) {
116 *type = WSCONS_EVENT_KEY_UP;
117 lks->down_keys_list[i] = -1;
118 return (1);
119 }
120 if (lks->down_keys_list[i] == -1 && freeslot == -1)
121 freeslot = i;
122 }
123
124 if (freeslot == -1) {
125 printf("lk201_decode: down(%d) no free slot\n", datain);
126 return (0);
127 }
128
129 *type = WSCONS_EVENT_KEY_DOWN;
130 lks->down_keys_list[freeslot] = datain;
131 return (1);
132 }
133
134 void
135 lk201_bell(lks, bell)
136 struct lk201_state *lks;
137 struct wskbd_bell_data *bell;
138 {
139 unsigned int vol;
140
141 if (bell->which & WSKBD_BELL_DOVOLUME) {
142 vol = 8 - bell->volume * 8 / 100;
143 if (vol > 7)
144 vol = 7;
145 } else
146 vol = 3;
147
148 if (vol != lks->bellvol) {
149 send(lks, LK_BELL_ENABLE);
150 send(lks, LK_PARAM_VOLUME(vol));
151 lks->bellvol = vol;
152 }
153 send(lks, LK_RING_BELL);
154 }
155
156 void
157 lk201_set_leds(lks, leds)
158 struct lk201_state *lks;
159 int leds;
160 {
161 int newleds;
162
163 newleds = 0;
164 if (leds & WSKBD_LED_SCROLL)
165 newleds |= LK_LED_WAIT;
166 if (leds & WSKBD_LED_CAPS)
167 newleds |= LK_LED_LOCK;
168
169 send(lks, LK_LED_DISABLE);
170 send(lks, (0x80 | (~newleds & 0x0f)));
171
172 send(lks, LK_LED_ENABLE);
173 send(lks, (0x80 | (newleds & 0x0f)));
174
175 lks->leds_state = leds;
176 }
177
178 void
179 lk201_set_keyclick(lks, vol)
180 struct lk201_state *lks;
181 int vol;
182 {
183 unsigned int newvol;
184
185 if (vol == 0)
186 send(lks, LK_CL_DISABLE);
187 else {
188 newvol = 8 - vol * 8 / 100;
189 if (newvol > 7)
190 newvol = 7;
191
192 send(lks, LK_CL_ENABLE);
193 send(lks, LK_PARAM_VOLUME(newvol));
194 }
195
196 lks->kcvol = vol;
197 }
Cache object: 7e9c946d1cf5abe06690cdd138149f5e
|