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