Home | History | Annotate | Line # | Download | only in tadpolectl
tadpolectl.c revision 1.8
      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