xref: /netbsd/usr.sbin/tadpolectl/tadpolectl.c (revision bf9ec67e)
1 /* $NetBSD: tadpolectl.c,v 1.5 2000/04/14 06:26:54 simonb Exp $ */
2 
3 /*-
4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Tim Rightnour.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the NetBSD
21  *      Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #include <ctype.h>
40 #include <err.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <fcntl.h>
45 #include <unistd.h>
46 #include <sys/ioctl.h>
47 #include <sys/types.h>
48 #include <sys/envsys.h>
49 #include <machine/apmvar.h>
50 #include <machine/tctrl.h>
51 
52 #define TCTRL_DEV	"/dev/tctrl0"
53 
54 int aflag, nflag, wflag, dev;
55 
56 #define PROTO(x) int x __P((int, int, int));
57 void usage __P((void));
58 static void parse __P((char *));
59 char *dashdot __P((char *));
60 int main __P((int, char *[]));
61 PROTO(hw_version)
62 PROTO(hw_microcontroller_version)
63 PROTO(hw_poweroncycles)
64 PROTO(hw_poweronseconds)
65 PROTO(hw_power_mains)
66 PROTO(hw_power_battery_int)
67 PROTO(hw_power_battery_ext)
68 PROTO(hw_power_battery_int_chargerate)
69 PROTO(hw_power_battery_ext_chargerate)
70 PROTO(hw_power_battery_int_chargelevel)
71 PROTO(hw_power_battery_ext_chargelevel)
72 PROTO(hw_video_external)
73 PROTO(hw_video_lid)
74 PROTO(hw_video_syncinva)
75 PROTO(hw_video_syncinvb)
76 PROTO(hw_video_compsync)
77 PROTO(hw_video_tft_brightness)
78 PROTO(hw_speaker_freq)
79 PROTO(hw_speaker_volume)
80 PROTO(hw_kbd_repeat_delay)
81 PROTO(hw_kbd_repeat_speed)
82 PROTO(hw_mouse_recalibrate)
83 PROTO(hw_power_battery_chargedisabled)
84 PROTO(hw_mouse_disable)
85 PROTO(hw_kbd_click)
86 PROTO(hw_mouse_intclick)
87 PROTO(hw_mouse_extclick)
88 PROTO(hw_mouse_sensitivity)
89 PROTO(hw_serial_power)
90 
91 #define NUM_MIBS 29
92 #define TABLE(n) { __STRING(n), 0, n }
93 
94 struct {
95 	char *mib;
96 	int value;
97 	int (*funcptr)(int, int, int);
98 } table[NUM_MIBS] = {
99 	TABLE(hw_microcontroller_version),
100 	TABLE(hw_version),
101 	TABLE(hw_poweroncycles),
102 	TABLE(hw_poweronseconds),
103 	TABLE(hw_power_mains),
104 	TABLE(hw_power_battery_int),
105 	TABLE(hw_power_battery_ext),
106 	TABLE(hw_power_battery_chargedisabled),
107 	TABLE(hw_power_battery_int_chargerate),
108 	TABLE(hw_power_battery_ext_chargerate),
109 	TABLE(hw_power_battery_int_chargelevel),
110 	TABLE(hw_power_battery_ext_chargelevel),
111 	TABLE(hw_video_external),
112 	TABLE(hw_video_lid),
113 	TABLE(hw_video_syncinva),
114 	TABLE(hw_video_syncinvb),
115 	TABLE(hw_video_compsync),
116 	TABLE(hw_video_tft_brightness),
117 	TABLE(hw_speaker_freq),
118 	TABLE(hw_speaker_volume),
119 	TABLE(hw_kbd_repeat_delay),
120 	TABLE(hw_kbd_repeat_speed),
121 	TABLE(hw_kbd_click),
122 	TABLE(hw_mouse_recalibrate),
123 	TABLE(hw_mouse_disable),
124 	TABLE(hw_mouse_intclick),
125 	TABLE(hw_mouse_extclick),
126 	TABLE(hw_mouse_sensitivity),
127 	TABLE(hw_serial_power),
128 };
129 
130 #define FUNC(x) \
131 int \
132 x(read, new, num) \
133 	int read, new, num;
134 
135 #define READ_REQ(a, b, c) \
136 	req.cmdbuf[0] = a; \
137 	req.cmdlen = b; \
138 	req.rsplen = c; \
139 	ioctl(dev, TCTRL_CMD_REQ, &req)
140 
141 #define WRITE_REQ(a, b, c) \
142 	req.cmdbuf[0] = a; \
143 	req.cmdlen = b; \
144 	req.rsplen = c; \
145 	ioctl(dev, TCTRL_CMD_REQ, &req)
146 
147 #define READ_ONLY \
148 	if (!read) \
149 		return(0)
150 
151 /* hardware functions */
152 
153 FUNC(hw_mouse_sensitivity)
154 {
155 	struct tctrl_req req;
156 
157 	req.cmdbuf[1] = 0xff;
158 	req.cmdbuf[2] = 0x00;
159 	READ_REQ(0x2c, 3, 2);
160 	table[num].value = req.rspbuf[0];
161 	if (read)
162 		return(1);
163 	if (new == 0)
164 		req.cmdbuf[2] = 0x00;
165 	else if (new > 255)
166 		req.cmdbuf[2] = 0xff;
167 	else
168 		req.cmdbuf[2] = new;
169 	req.cmdbuf[1] = 0x00;
170 	WRITE_REQ(0x2c, 3, 2);
171 	req.cmdbuf[1] = 0xff;
172 	req.cmdbuf[2] = 0x00;
173 	READ_REQ(0x2c, 3, 2);
174 	table[num].value = req.rspbuf[0];
175 	return(1);
176 }
177 
178 FUNC(hw_power_battery_chargedisabled)
179 {
180 	struct tctrl_req req;
181 
182 	req.cmdbuf[1] = 0xff;
183 	req.cmdbuf[2] = 0x00;
184 	READ_REQ(0x22, 3, 2);
185 	table[num].value = req.rspbuf[0]&0x01 ? 1 : 0;
186 	if (read)
187 		return(1);
188 	if (new == 0)
189 		req.cmdbuf[2] = 0x00;
190 	else
191 		req.cmdbuf[2] = 0x01;
192 	req.cmdbuf[1] = ~0x01;
193 	WRITE_REQ(0x22, 3, 2);
194 	req.cmdbuf[1] = 0xff;
195 	req.cmdbuf[2] = 0x00;
196 	READ_REQ(0x22, 3, 2);
197 	table[num].value = req.rspbuf[0]&0x01 ? 1 : 0;
198 	return(1);
199 }
200 
201 FUNC(hw_mouse_disable)
202 {
203 	struct tctrl_req req;
204 
205 	req.cmdbuf[1] = 0xff;
206 	req.cmdbuf[2] = 0x00;
207 	READ_REQ(0x22, 3, 2);
208 	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
209 	if (read)
210 		return(1);
211 	if (new == 0)
212 		req.cmdbuf[2] = 0x00;
213 	else
214 		req.cmdbuf[2] = 0x02;
215 	req.cmdbuf[1] = ~0x02;
216 	WRITE_REQ(0x22, 3, 2);
217 	req.cmdbuf[1] = 0xff;
218 	req.cmdbuf[2] = 0x00;
219 	READ_REQ(0x22, 3, 2);
220 	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
221 	return(1);
222 }
223 
224 FUNC(hw_kbd_click)
225 {
226 	struct tctrl_req req;
227 
228 	req.cmdbuf[1] = 0xff;
229 	req.cmdbuf[2] = 0x00;
230 	READ_REQ(0x22, 3, 2);
231 	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
232 	if (read)
233 		return(1);
234 	if (new == 0)
235 		req.cmdbuf[2] = 0x00;
236 	else
237 		req.cmdbuf[2] = 0x04;
238 	req.cmdbuf[1] = ~0x04;
239 	WRITE_REQ(0x22, 3, 2);
240 	req.cmdbuf[1] = 0xff;
241 	req.cmdbuf[2] = 0x00;
242 	READ_REQ(0x22, 3, 2);
243 	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
244 	return(1);
245 }
246 
247 FUNC(hw_mouse_intclick)
248 {
249 	struct tctrl_req req;
250 
251 	req.cmdbuf[1] = 0xff;
252 	req.cmdbuf[2] = 0x00;
253 	READ_REQ(0x22, 3, 2);
254 	table[num].value = req.rspbuf[0]&0x08 ? 1 : 0;
255 	if (read)
256 		return(1);
257 	if (new == 0)
258 		req.cmdbuf[2] = 0x00;
259 	else
260 		req.cmdbuf[2] = 0x08;
261 	req.cmdbuf[1] = ~0x08;
262 	WRITE_REQ(0x22, 3, 2);
263 	req.cmdbuf[1] = 0xff;
264 	req.cmdbuf[2] = 0x00;
265 	READ_REQ(0x22, 3, 2);
266 	table[num].value = req.rspbuf[0]&0x08 ? 1 : 0;
267 	return(1);
268 }
269 
270 FUNC(hw_mouse_extclick)
271 {
272 	struct tctrl_req req;
273 
274 	req.cmdbuf[1] = 0xff;
275 	req.cmdbuf[2] = 0x00;
276 	READ_REQ(0x22, 3, 2);
277 	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
278 	if (read)
279 		return(1);
280 	if (new == 0)
281 		req.cmdbuf[2] = 0x00;
282 	else
283 		req.cmdbuf[2] = 0x10;
284 	req.cmdbuf[1] = ~0x10;
285 	WRITE_REQ(0x22, 3, 2);
286 	req.cmdbuf[1] = 0xff;
287 	req.cmdbuf[2] = 0x00;
288 	READ_REQ(0x22, 3, 2);
289 	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
290 	return(1);
291 }
292 
293 /* ARGSUSED */
294 FUNC(hw_mouse_recalibrate)
295 {
296 	struct tctrl_req req;
297 
298 	table[num].value = 0;
299 	if (read)
300 		return(1);
301 	READ_REQ(0x36, 1, 1);
302 	return(1);
303 }
304 
305 FUNC(hw_kbd_repeat_delay)
306 {
307 	struct tctrl_req req;
308 
309 	req.cmdbuf[1] = 0xff;
310 	req.cmdbuf[2] = 0x00;
311 	READ_REQ(0x28, 3, 2);
312 	table[num].value = req.rspbuf[0];
313 	if (read)
314 		return(1);
315 	if (new == 0)
316 		req.cmdbuf[2] = 0x00;
317 	else if (new > 255)
318 		req.cmdbuf[2] = 0xff;
319 	else
320 		req.cmdbuf[2] = new;
321 	req.cmdbuf[1] = 0x00;
322 	WRITE_REQ(0x28, 3, 2);
323 	req.cmdbuf[1] = 0xff;
324 	req.cmdbuf[2] = 0x00;
325 	READ_REQ(0x28, 3, 2);
326 	table[num].value = req.rspbuf[0];
327 	return(1);
328 }
329 
330 FUNC(hw_kbd_repeat_speed)
331 {
332 	struct tctrl_req req;
333 
334 	req.cmdbuf[1] = 0xff;
335 	req.cmdbuf[2] = 0x00;
336 	READ_REQ(0x29, 3, 2);
337 	table[num].value = req.rspbuf[0];
338 	if (read)
339 		return(1);
340 	if (new == 0)
341 		req.cmdbuf[2] = 0x00;
342 	else if (new > 255)
343 		req.cmdbuf[2] = 0xff;
344 	else
345 		req.cmdbuf[2] = new;
346 	req.cmdbuf[1] = 0x00;
347 	WRITE_REQ(0x29, 3, 2);
348 	req.cmdbuf[1] = 0xff;
349 	req.cmdbuf[2] = 0x00;
350 	READ_REQ(0x29, 3, 2);
351 	table[num].value = req.rspbuf[0];
352 	return(1);
353 }
354 
355 FUNC(hw_speaker_freq)
356 {
357 	struct tctrl_req req;
358 
359 	table[num].value = 0;
360 	if (read)
361 		return(1);
362 	req.cmdbuf[1] = new * 256;
363 	req.cmdbuf[2] = new % 256;
364 	WRITE_REQ(0x37, 3, 1);
365 	return(1);
366 }
367 
368 FUNC(hw_speaker_volume)
369 {
370 	struct tctrl_req req;
371 
372 	req.cmdbuf[1] = 0xff;
373 	req.cmdbuf[2] = 0x00;
374 	READ_REQ(0x23, 3, 2);
375 	table[num].value = req.rspbuf[0];
376 	if (read)
377 		return(1);
378 	if (new == 0)
379 		req.cmdbuf[2] = 0x00;
380 	else if (new > 255)
381 		req.cmdbuf[2] = 0xff;
382 	else
383 		req.cmdbuf[2] = new;
384 	req.cmdbuf[1] = 0x00;
385 	WRITE_REQ(0x23, 3, 2);
386 	req.cmdbuf[1] = 0xff;
387 	req.cmdbuf[2] = 0x00;
388 	READ_REQ(0x23, 3, 2);
389 	table[num].value = req.rspbuf[0];
390 	return(1);
391 }
392 
393 FUNC(hw_video_tft_brightness)
394 {
395 	struct tctrl_req req;
396 
397 	req.cmdbuf[1] = 0xff;
398 	req.cmdbuf[2] = 0x00;
399 	READ_REQ(0x24, 3, 2);
400 	table[num].value = req.rspbuf[0];
401 	if (read)
402 		return(1);
403 	if (new == 0)
404 		req.cmdbuf[2] = 0x00;
405 	else if (new > 255)
406 		req.cmdbuf[2] = 0xff;
407 	else
408 		req.cmdbuf[2] = new;
409 	req.cmdbuf[1] = 0x00;
410 	WRITE_REQ(0x24, 3, 2);
411 	req.cmdbuf[1] = 0xff;
412 	req.cmdbuf[2] = 0x00;
413 	READ_REQ(0x24, 3, 2);
414 	table[num].value = req.rspbuf[0];
415 	return(1);
416 }
417 
418 FUNC(hw_video_syncinva)
419 {
420 	struct tctrl_req req;
421 
422 	req.cmdbuf[1] = 0xff;
423 	req.cmdbuf[2] = 0x00;
424 	READ_REQ(0x21, 3, 2);
425 	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
426 	if (read)
427 		return(1);
428 	if (new == 0)
429 		req.cmdbuf[2] = 0x00;
430 	else
431 		req.cmdbuf[2] = 0x02;
432 	req.cmdbuf[1] = ~0x02;
433 	WRITE_REQ(0x21, 3, 2);
434 	req.cmdbuf[1] = 0xff;
435 	req.cmdbuf[2] = 0x00;
436 	READ_REQ(0x21, 3, 2);
437 	table[num].value = req.rspbuf[0]&0x02 ? 1 : 0;
438 	return(1);
439 }
440 
441 FUNC(hw_video_syncinvb)
442 {
443 	struct tctrl_req req;
444 
445 	req.cmdbuf[1] = 0xff;
446 	req.cmdbuf[2] = 0x00;
447 	READ_REQ(0x21, 3, 2);
448 	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
449 	if (read)
450 		return(1);
451 	if (new == 0)
452 		req.cmdbuf[2] = 0x00;
453 	else
454 		req.cmdbuf[2] = 0x04;
455 	req.cmdbuf[1] = ~0x04;
456 	WRITE_REQ(0x21, 3, 2);
457 	req.cmdbuf[1] = 0xff;
458 	req.cmdbuf[2] = 0x00;
459 	READ_REQ(0x21, 3, 2);
460 	table[num].value = req.rspbuf[0]&0x04 ? 1 : 0;
461 	return(1);
462 }
463 
464 FUNC(hw_video_compsync)
465 {
466 	struct tctrl_req req;
467 
468 	req.cmdbuf[1] = 0xff;
469 	req.cmdbuf[2] = 0x00;
470 	READ_REQ(0x21, 3, 2);
471 	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
472 	if (read)
473 		return(1);
474 	if (new == 0)
475 		req.cmdbuf[2] = 0x00;
476 	else
477 		req.cmdbuf[2] = 0x10;
478 	req.cmdbuf[1] = ~0x10;
479 	WRITE_REQ(0x21, 3, 2);
480 	req.cmdbuf[1] = 0xff;
481 	req.cmdbuf[2] = 0x00;
482 	READ_REQ(0x21, 3, 2);
483 	table[num].value = req.rspbuf[0]&0x10 ? 1 : 0;
484 	return(1);
485 }
486 
487 /* ARGSUSED */
488 FUNC(hw_video_lid)
489 {
490 	struct tctrl_req req;
491 	short i;
492 
493 	READ_ONLY;
494 	READ_REQ(0x11, 1, 3);
495 	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
496 	table[num].value = i&0x0040 ? 0 : 1;
497 	return(1);
498 }
499 
500 /* ARGSUSED */
501 FUNC(hw_video_external)
502 {
503 	struct tctrl_req req;
504 	short i;
505 
506 	READ_ONLY;
507 	READ_REQ(0x11, 1, 3);
508 	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
509 	table[num].value = i&0x0008 ? 1 : 0;
510 	return(1);
511 }
512 
513 /* ARGSUSED */
514 FUNC(hw_power_battery_int_chargelevel)
515 {
516 	struct tctrl_req req;
517 
518 	READ_ONLY;
519 	READ_REQ(0x7a, 1, 3);
520 	table[num].value = req.rspbuf[0] == 0xfb ? 0 : req.rspbuf[0];
521 	return(1);
522 
523 }
524 
525 /* ARGSUSED */
526 FUNC(hw_power_battery_ext_chargelevel)
527 {
528 	struct tctrl_req req;
529 
530 	READ_ONLY;
531 	READ_REQ(0x7b, 1, 3);
532 	table[num].value = req.rspbuf[0] == 0xfb ? 0 : req.rspbuf[0];
533 	return(1);
534 }
535 
536 FUNC(hw_power_battery_int_chargerate)
537 {
538 	struct tctrl_req req;
539 
540 	READ_REQ(0x18, 1, 2);
541 	table[num].value = req.rspbuf[0];
542 	if (read)
543 		return(1);
544 	req.cmdbuf[1] = new < 255 ? new : 255;
545 	WRITE_REQ(0x39, 2, 1);
546 	READ_REQ(0x18, 1, 2);
547 	table[num].value = req.rspbuf[0];
548 	return(1);
549 }
550 
551 FUNC(hw_power_battery_ext_chargerate)
552 {
553 	struct tctrl_req req;
554 
555 	READ_REQ(0x18, 1, 2);
556 	table[num].value = req.rspbuf[0];
557 	if (read)
558 		return(1);
559 	req.cmdbuf[1] = new < 255 ? new : 255;
560 	WRITE_REQ(0x39, 2, 1);
561 	READ_REQ(0x18, 1, 2);
562 	table[num].value = req.rspbuf[0];
563 	return(1);
564 }
565 
566 /* ARGSUSED */
567 FUNC(hw_power_battery_ext)
568 {
569 	int i;
570 	struct tctrl_req req;
571 
572 	READ_ONLY;
573 	READ_REQ(0x11, 1, 3);
574 	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
575 	table[num].value = i&0x0004 ? 1 : 0;
576 	return(1);
577 }
578 
579 /* ARGSUSED */
580 FUNC(hw_power_battery_int)
581 {
582 	int i;
583 	struct tctrl_req req;
584 
585 	READ_ONLY;
586 	READ_REQ(0x11, 1, 3);
587 	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
588 	table[num].value = i&0x0002 ? 1 : 0;
589 	return(1);
590 }
591 
592 /* ARGSUSED */
593 FUNC(hw_power_mains)
594 {
595 	int i;
596 	struct tctrl_req req;
597 
598 	READ_ONLY;
599 	READ_REQ(0x11, 1, 3);
600 	i = (req.rspbuf[0]<<8) + req.rspbuf[1];
601 	table[num].value = i&0x0001 ? 1 : 0;
602 	return(1);
603 }
604 
605 /* ARGSUSED */
606 FUNC(hw_poweroncycles)
607 {
608 	struct tctrl_req req;
609 
610 	READ_ONLY;
611 	READ_REQ(0x09, 1, 5);
612 	table[num].value = (req.rspbuf[0]<<24)+(req.rspbuf[1]<<16)+
613 	    (req.rspbuf[2]<<8)+req.rspbuf[3];
614 	return(1);
615 }
616 
617 /* ARGSUSED */
618 FUNC(hw_poweronseconds)
619 {
620 	struct tctrl_req req;
621 
622 	READ_ONLY;
623 	READ_REQ(0x0a, 1, 5);
624 	table[num].value = (req.rspbuf[0]<<24)+(req.rspbuf[1]<<16)+
625 	    (req.rspbuf[2]<<8)+req.rspbuf[3];
626 	return(1);
627 }
628 
629 /* ARGSUSED */
630 FUNC(hw_microcontroller_version)
631 {
632 	char *bufp, buf[BUFSIZ];
633 	struct tctrl_req req;
634 
635 	READ_ONLY;
636 	READ_REQ(0x04, 1, 3);
637 	bufp = buf;
638 	sprintf(bufp, "%d%d", req.rspbuf[0]*1000, req.rspbuf[1]*10);
639 	table[num].value = atoi(strdup(bufp));
640 	return(1);
641 }
642 
643 
644 /* ARGSUSED */
645 FUNC(hw_version)
646 {
647 	char *bufp, buf[BUFSIZ];
648 	struct tctrl_req req;
649 
650 	READ_ONLY;
651 	READ_REQ(0x03, 1, 3);
652 	bufp = buf;
653 	sprintf(bufp, "%d%d", req.rspbuf[0]*1000, req.rspbuf[1]*10);
654 	table[num].value = atoi(strdup(bufp));
655 	return(1);
656 }
657 
658 FUNC(hw_serial_power)
659 {
660 	struct tctrl_pwr pwrreq;
661 
662 	if (!read) {
663 		pwrreq.rw = 0x00;
664 		pwrreq.state = new;
665 		ioctl(dev, TCTRL_SERIAL_PWR, &pwrreq);
666 	}
667 	pwrreq.rw = 0x01;
668 	ioctl(dev, TCTRL_SERIAL_PWR, &pwrreq);
669 	table[num].value = pwrreq.state;
670 	return(1);
671 }
672 
673 void
674 usage()
675 {
676 	(void)fprintf(stderr,
677 	    "usage: tadpolectl [-n] name ...\n"
678 	    "       tadpolectl [-n] -w name=value\n"
679 	    "       tadpolectl [-n] -a\n");
680 	exit(1);
681 }
682 
683 static void
684 parse(string)
685 	char *string;
686 {
687 	char *cp, buf[BUFSIZ];
688 	int newval = 0;
689 	int i, j, ret;
690 
691 	string = dashdot(string);
692 	snprintf(buf, (size_t)BUFSIZ, "%s", string);
693 	if ((cp = strchr(string, '=')) != NULL) {
694 		if (!wflag)
695 			errx(2, "Must specify -w to set variables");
696 		*strchr(buf, '=') = '\0';
697 		*cp++ = '\0';
698 		while (isspace((unsigned char) *cp))
699 			cp++;
700 		newval = atoi(cp);
701 	}
702 	for (j=0,i=-1; j < NUM_MIBS; j++) {
703 		if (strcmp(string, table[j].mib) == 0) {
704 			i = j;
705 			break;
706 		}
707 	}
708 	if (i == -1)
709 		errx(2, "Named value does not exist");
710 
711 	if (wflag) {
712 		ret = (*table[i].funcptr)(0, newval, i);
713 		if (!ret)
714 			errx(2, "Cannot modify this value");
715 	} else
716 		ret = (*table[i].funcptr)(1, 0, i);
717 	if (nflag)
718 		printf("%d\n", table[i].value);
719 	else
720 		printf("%s = %d\n", dashdot(table[i].mib), table[i].value);
721 }
722 
723 char *
724 dashdot(string)
725 	char *string;
726 {
727 	char *p;
728 	char *save;
729 
730 	p = strdup(string);
731 	save = p;
732 
733 	for (; (*p = *string) != '\0'; ++p, ++string) {
734 		if (*p == '.')
735 			*p = '_';
736 		else if (*p == '_')
737 			*p = '.';
738 	}
739 	return(save);
740 }
741 
742 int
743 main(argc, argv)
744 	int argc;
745 	char *argv[];
746 {
747 	int ch, j;
748 
749 	while ((ch = getopt(argc, argv, "anw")) != -1) {
750 		switch (ch) {
751 
752 		case 'a':
753 			aflag = 1;
754 			break;
755 		case 'n':
756 			nflag = 1;
757 			break;
758 		case 'w':
759 			wflag = 1;
760 			break;
761 		default:
762 			usage();
763 		}
764 	}
765 	argc -= optind;
766 	argv += optind;
767 
768 	if ((dev = open(TCTRL_DEV, O_RDONLY, NULL)) == -1)
769 		err(1, "%s", TCTRL_DEV);
770 
771 	if (aflag) {
772 		for (j=0; j < NUM_MIBS; j++) {
773 			(void)(*table[j].funcptr)(1, 0, j);
774 			if (nflag)
775 				printf("%d\n", table[j].value);
776 			else
777 				printf("%s = %d\n", dashdot(table[j].mib),
778 				    table[j].value);
779 		}
780 		return(0);
781 	}
782 	if (argc == 0)
783 		usage();
784 	while (argc-- > 0)
785 		parse(*argv++);
786 	return(0);
787 }
788