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