Home | History | Annotate | Line # | Download | only in tadpolectl
tadpolectl.c revision 1.6
      1 /* $NetBSD: tadpolectl.c,v 1.6 2003/07/13 12:09:56 itojun 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 buf[BUFSIZ];
    633 	struct tctrl_req req;
    634 
    635 	READ_ONLY;
    636 	READ_REQ(0x04, 1, 3);
    637 	snprintf(buf, sizeof(buf), "%d%d", req.rspbuf[0]*1000,
    638 	    req.rspbuf[1]*10);
    639 	table[num].value = atoi(strdup(buf));
    640 	return(1);
    641 }
    642 
    643 
    644 /* ARGSUSED */
    645 FUNC(hw_version)
    646 {
    647 	char buf[BUFSIZ];
    648 	struct tctrl_req req;
    649 
    650 	READ_ONLY;
    651 	READ_REQ(0x03, 1, 3);
    652 	snprintf(buf, sizeof(buf), "%d%d", req.rspbuf[0]*1000,
    653 	    req.rspbuf[1]*10);
    654 	table[num].value = atoi(strdup(buf));
    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