Home | History | Annotate | Line # | Download | only in ic
hd44780_subr.c revision 1.3
      1  1.2   joff /* $NetBSD: hd44780_subr.c,v 1.3 2005/01/09 15:43:56 joff Exp $ */
      2  1.1  soren 
      3  1.1  soren /*
      4  1.1  soren  * Copyright (c) 2002 Dennis I. Chernoivanov
      5  1.1  soren  * All rights reserved.
      6  1.1  soren  *
      7  1.1  soren  * Redistribution and use in source and binary forms, with or without
      8  1.1  soren  * modification, are permitted provided that the following conditions
      9  1.1  soren  * are met:
     10  1.1  soren  * 1. Redistributions of source code must retain the above copyright
     11  1.1  soren  *    notice, this list of conditions and the following disclaimer.
     12  1.1  soren  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  soren  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  soren  *    documentation and/or other materials provided with the distribution.
     15  1.1  soren  * 3. The name of the author may not be used to endorse or promote products
     16  1.1  soren  *    derived from this software without specific prior written permission
     17  1.1  soren  *
     18  1.1  soren  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  1.1  soren  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  1.1  soren  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  1.1  soren  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  1.1  soren  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23  1.1  soren  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24  1.1  soren  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25  1.1  soren  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  1.1  soren  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  1.1  soren  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  1.1  soren  */
     29  1.1  soren 
     30  1.1  soren /*
     31  1.1  soren  * Subroutines for Hitachi HD44870 style displays
     32  1.1  soren  */
     33  1.1  soren 
     34  1.1  soren #include <sys/cdefs.h>
     35  1.2   joff __KERNEL_RCSID(0, "$NetBSD: hd44780_subr.c,v 1.3 2005/01/09 15:43:56 joff Exp $");
     36  1.1  soren 
     37  1.1  soren #include <sys/param.h>
     38  1.1  soren #include <sys/systm.h>
     39  1.1  soren #include <sys/conf.h>
     40  1.1  soren #include <sys/kernel.h>
     41  1.1  soren #include <sys/types.h>
     42  1.1  soren #include <sys/ioccom.h>
     43  1.1  soren 
     44  1.1  soren #include <machine/autoconf.h>
     45  1.1  soren #include <machine/intr.h>
     46  1.1  soren #include <machine/bus.h>
     47  1.1  soren 
     48  1.1  soren #include <dev/ic/hd44780reg.h>
     49  1.1  soren #include <dev/ic/hd44780_subr.h>
     50  1.1  soren 
     51  1.1  soren /*
     52  1.1  soren  * Finish device attach. sc_writereg, sc_readreg and sc_flags must be properly
     53  1.1  soren  * initialized prior to this call.
     54  1.1  soren  */
     55  1.1  soren void
     56  1.1  soren hd44780_attach_subr(sc)
     57  1.1  soren 	struct hd44780_chip *sc;
     58  1.1  soren {
     59  1.3   joff 	int err = 0;
     60  1.1  soren 	/* Putc/getc are supposed to be set by platform-dependent code. */
     61  1.2   joff 	if ((sc->sc_writereg == NULL) || (sc->sc_readreg == NULL))
     62  1.1  soren 		sc->sc_dev_ok = 0;
     63  1.1  soren 
     64  1.1  soren 	/* Make sure that HD_MAX_CHARS is enough. */
     65  1.1  soren 	if ((sc->sc_flags & HD_MULTILINE) && (2 * sc->sc_rows > HD_MAX_CHARS))
     66  1.1  soren 		sc->sc_dev_ok = 0;
     67  1.1  soren 	else if (sc->sc_rows > HD_MAX_CHARS)
     68  1.1  soren 		sc->sc_dev_ok = 0;
     69  1.1  soren 
     70  1.1  soren 	if (sc->sc_dev_ok) {
     71  1.3   joff 		if ((sc->sc_flags & HD_UP) == 0)
     72  1.3   joff 			err = hd44780_init(sc);
     73  1.3   joff 		if (err != 0)
     74  1.3   joff 			printf("%s: not responding or unconnected\n", sc->sc_dev->dv_xname);
     75  1.1  soren 
     76  1.1  soren 	}
     77  1.1  soren }
     78  1.1  soren 
     79  1.1  soren /*
     80  1.1  soren  * Initialize 4-bit or 8-bit connected device.
     81  1.1  soren  */
     82  1.3   joff int
     83  1.1  soren hd44780_init(sc)
     84  1.1  soren 	struct hd44780_chip *sc;
     85  1.1  soren {
     86  1.3   joff 	u_int8_t cmd, dat;
     87  1.1  soren 
     88  1.3   joff 	sc->sc_flags &= ~(HD_TIMEDOUT|HD_UP);
     89  1.3   joff 	sc->sc_dev_ok = 1;
     90  1.1  soren 	cmd = cmd_init(sc->sc_flags & HD_8BIT);
     91  1.2   joff 	hd44780_ir_write(sc, cmd);
     92  1.2   joff 	delay(HD_TIMEOUT_LONG);
     93  1.2   joff 	hd44780_ir_write(sc, cmd);
     94  1.2   joff 	hd44780_ir_write(sc, cmd);
     95  1.1  soren 
     96  1.1  soren 	cmd = cmd_funcset(
     97  1.1  soren 			sc->sc_flags & HD_8BIT,
     98  1.1  soren 			sc->sc_flags & HD_MULTILINE,
     99  1.1  soren 			sc->sc_flags & HD_BIGFONT);
    100  1.1  soren 
    101  1.1  soren 	if ((sc->sc_flags & HD_8BIT) == 0)
    102  1.2   joff 		hd44780_ir_write(sc, cmd);
    103  1.1  soren 
    104  1.2   joff 	sc->sc_flags |= HD_UP;
    105  1.2   joff 
    106  1.2   joff 	hd44780_ir_write(sc, cmd);
    107  1.2   joff 	hd44780_ir_write(sc, cmd_dispctl(0, 0, 0));
    108  1.2   joff 	hd44780_ir_write(sc, cmd_clear());
    109  1.2   joff 	hd44780_ir_write(sc, cmd_modset(1, 0));
    110  1.3   joff 
    111  1.3   joff 	if (sc->sc_flags & HD_TIMEDOUT) {
    112  1.3   joff 		sc->sc_flags &= ~HD_UP;
    113  1.3   joff 		return EIO;
    114  1.3   joff 	}
    115  1.3   joff 
    116  1.3   joff 	/* Turn display on and clear it. */
    117  1.3   joff 	hd44780_ir_write(sc, cmd_clear());
    118  1.3   joff 	hd44780_ir_write(sc, cmd_dispctl(1, 0, 0));
    119  1.3   joff 
    120  1.3   joff 	/* Attempt a simple probe for presence */
    121  1.3   joff 	hd44780_ir_write(sc, cmd_ddramset(0x5));
    122  1.3   joff 	hd44780_ir_write(sc, cmd_shift(0, 1));
    123  1.3   joff 	hd44780_busy_wait(sc);
    124  1.3   joff 	if ((dat = hd44780_ir_read(sc) & 0x7f) != 0x6) {
    125  1.3   joff 		sc->sc_dev_ok = 0;
    126  1.3   joff 		sc->sc_flags &= ~HD_UP;
    127  1.3   joff 		return EIO;
    128  1.3   joff 	}
    129  1.3   joff 	hd44780_ir_write(sc, cmd_ddramset(0));
    130  1.3   joff 
    131  1.3   joff 	return 0;
    132  1.1  soren }
    133  1.1  soren 
    134  1.1  soren /*
    135  1.1  soren  * Standard hd44780 ioctl() functions.
    136  1.1  soren  */
    137  1.1  soren int
    138  1.1  soren hd44780_ioctl_subr(sc, cmd, data)
    139  1.1  soren 	struct hd44780_chip *sc;
    140  1.1  soren 	u_long cmd;
    141  1.1  soren 	caddr_t data;
    142  1.1  soren {
    143  1.1  soren 	u_int8_t tmp;
    144  1.1  soren 	int error = 0;
    145  1.1  soren 
    146  1.1  soren #define hd44780_io()	((struct hd44780_io *)data)
    147  1.1  soren #define hd44780_info()	((struct hd44780_info*)data)
    148  1.1  soren #define hd44780_ctrl()	((struct hd44780_dispctl*)data)
    149  1.1  soren 
    150  1.1  soren 	switch (cmd) {
    151  1.1  soren 		/* Clear the LCD. */
    152  1.1  soren 		case HLCD_CLEAR:
    153  1.1  soren 			hd44780_ir_write(sc, cmd_clear());
    154  1.1  soren 			break;
    155  1.1  soren 
    156  1.1  soren 		/* Move the cursor one position to the left. */
    157  1.1  soren 		case HLCD_CURSOR_LEFT:
    158  1.1  soren 			hd44780_ir_write(sc, cmd_shift(0, 0));
    159  1.1  soren 			break;
    160  1.1  soren 
    161  1.1  soren 		/* Move the cursor one position to the right. */
    162  1.1  soren 		case HLCD_CURSOR_RIGHT:
    163  1.1  soren 			hd44780_ir_write(sc, cmd_shift(0, 1));
    164  1.1  soren 			break;
    165  1.1  soren 
    166  1.1  soren 		/* Control the LCD. */
    167  1.1  soren 		case HLCD_DISPCTL:
    168  1.1  soren 			hd44780_ir_write(sc, cmd_dispctl(
    169  1.1  soren 						hd44780_ctrl()->display_on,
    170  1.1  soren 						hd44780_ctrl()->cursor_on,
    171  1.1  soren 						hd44780_ctrl()->blink_on));
    172  1.1  soren 			break;
    173  1.1  soren 
    174  1.1  soren 		/* Get LCD configuration. */
    175  1.1  soren 		case HLCD_GET_INFO:
    176  1.1  soren 			hd44780_info()->lines
    177  1.1  soren 				= (sc->sc_flags & HD_MULTILINE) ? 2 : 1;
    178  1.1  soren 			hd44780_info()->phys_rows = sc->sc_rows;
    179  1.1  soren 			hd44780_info()->virt_rows = sc->sc_vrows;
    180  1.1  soren 			hd44780_info()->is_wide = sc->sc_flags & HD_8BIT;
    181  1.1  soren 			hd44780_info()->is_bigfont = sc->sc_flags & HD_BIGFONT;
    182  1.1  soren 			hd44780_info()->kp_present = sc->sc_flags & HD_KEYPAD;
    183  1.1  soren 			break;
    184  1.1  soren 
    185  1.1  soren 
    186  1.1  soren 		/* Reset the LCD. */
    187  1.1  soren 		case HLCD_RESET:
    188  1.3   joff 			error = hd44780_init(sc);
    189  1.1  soren 			break;
    190  1.1  soren 
    191  1.1  soren 		/* Get the current cursor position. */
    192  1.1  soren 		case HLCD_GET_CURSOR_POS:
    193  1.1  soren 			hd44780_io()->dat = (hd44780_ir_read(sc) & 0x7f);
    194  1.1  soren 			break;
    195  1.1  soren 
    196  1.1  soren 		/* Set the cursor position. */
    197  1.1  soren 		case HLCD_SET_CURSOR_POS:
    198  1.1  soren 			hd44780_ir_write(sc, cmd_ddramset(hd44780_io()->dat));
    199  1.1  soren 			break;
    200  1.1  soren 
    201  1.1  soren 		/* Get the value at the current cursor position. */
    202  1.1  soren 		case HLCD_GETC:
    203  1.1  soren 			tmp = (hd44780_ir_read(sc) & 0x7f);
    204  1.1  soren 			hd44780_ir_write(sc, cmd_ddramset(tmp));
    205  1.1  soren 			hd44780_io()->dat = hd44780_dr_read(sc);
    206  1.1  soren 			break;
    207  1.1  soren 
    208  1.1  soren 		/* Set the character at the cursor position + advance cursor. */
    209  1.1  soren 		case HLCD_PUTC:
    210  1.1  soren 			hd44780_dr_write(sc, hd44780_io()->dat);
    211  1.1  soren 			break;
    212  1.1  soren 
    213  1.1  soren 		/* Shift display left. */
    214  1.1  soren 		case HLCD_SHIFT_LEFT:
    215  1.1  soren 			hd44780_ir_write(sc, cmd_shift(1, 0));
    216  1.1  soren 			break;
    217  1.1  soren 
    218  1.1  soren 		/* Shift display right. */
    219  1.1  soren 		case HLCD_SHIFT_RIGHT:
    220  1.1  soren 			hd44780_ir_write(sc, cmd_shift(1, 1));
    221  1.1  soren 			break;
    222  1.1  soren 
    223  1.1  soren 		/* Return home. */
    224  1.1  soren 		case HLCD_HOME:
    225  1.1  soren 			hd44780_ir_write(sc, cmd_rethome());
    226  1.1  soren 			break;
    227  1.1  soren 
    228  1.1  soren 		/* Write a string to the LCD virtual area. */
    229  1.1  soren 		case HLCD_WRITE:
    230  1.1  soren 			error = hd44780_ddram_io(sc, hd44780_io(), HD_DDRAM_WRITE);
    231  1.1  soren 			break;
    232  1.1  soren 
    233  1.1  soren 		/* Read LCD virtual area. */
    234  1.1  soren 		case HLCD_READ:
    235  1.1  soren 			error = hd44780_ddram_io(sc, hd44780_io(), HD_DDRAM_READ);
    236  1.1  soren 			break;
    237  1.1  soren 
    238  1.1  soren 		/* Write to the LCD visible area. */
    239  1.1  soren 		case HLCD_REDRAW:
    240  1.1  soren 			hd44780_ddram_redraw(sc, hd44780_io());
    241  1.1  soren 			break;
    242  1.1  soren 
    243  1.1  soren 		/* Write raw instruction. */
    244  1.1  soren 		case HLCD_WRITE_INST:
    245  1.1  soren 			hd44780_ir_write(sc, hd44780_io()->dat);
    246  1.1  soren 			break;
    247  1.1  soren 
    248  1.1  soren 		/* Write raw data. */
    249  1.1  soren 		case HLCD_WRITE_DATA:
    250  1.1  soren 			hd44780_dr_write(sc, hd44780_io()->dat);
    251  1.1  soren 			break;
    252  1.1  soren 
    253  1.1  soren 		default:
    254  1.1  soren 			error = EINVAL;
    255  1.1  soren 	}
    256  1.1  soren 
    257  1.3   joff 	if (sc->sc_flags & HD_TIMEDOUT)
    258  1.3   joff 		error = EIO;
    259  1.3   joff 
    260  1.1  soren 	return error;
    261  1.1  soren }
    262  1.1  soren 
    263  1.1  soren /*
    264  1.1  soren  * Read/write particular area of the LCD screen.
    265  1.1  soren  */
    266  1.1  soren int
    267  1.1  soren hd44780_ddram_io(sc, io, dir)
    268  1.1  soren 	struct hd44780_chip *sc;
    269  1.1  soren 	struct hd44780_io *io;
    270  1.1  soren 	u_char dir;
    271  1.1  soren {
    272  1.1  soren 	u_int8_t hi;
    273  1.1  soren 	u_int8_t addr;
    274  1.1  soren 
    275  1.1  soren 	int error = 0;
    276  1.1  soren 	u_int8_t i = 0;
    277  1.1  soren 
    278  1.1  soren 	if (io->dat < sc->sc_vrows) {
    279  1.1  soren 		hi = HD_ROW1_ADDR + sc->sc_vrows;
    280  1.1  soren 		addr = HD_ROW1_ADDR + io->dat;
    281  1.1  soren 		for (; (addr < hi) && (i < io->len); addr++, i++) {
    282  1.1  soren 			hd44780_ir_write(sc, cmd_ddramset(addr));
    283  1.1  soren 			if (dir == HD_DDRAM_READ)
    284  1.1  soren 				io->buf[i] = hd44780_dr_read(sc);
    285  1.1  soren 			else
    286  1.1  soren 				hd44780_dr_write(sc, io->buf[i]);
    287  1.1  soren 		}
    288  1.1  soren 	}
    289  1.1  soren 	if (io->dat < 2 * sc->sc_vrows) {
    290  1.1  soren 		hi = HD_ROW2_ADDR + sc->sc_vrows;
    291  1.1  soren 		if (io->dat >= sc->sc_vrows)
    292  1.1  soren 			addr = HD_ROW2_ADDR + io->dat - sc->sc_vrows;
    293  1.1  soren 		else
    294  1.1  soren 			addr = HD_ROW2_ADDR;
    295  1.1  soren 		for (; (addr < hi) && (i < io->len); addr++, i++) {
    296  1.1  soren 			hd44780_ir_write(sc, cmd_ddramset(addr));
    297  1.1  soren 			if (dir == HD_DDRAM_READ)
    298  1.1  soren 				io->buf[i] = hd44780_dr_read(sc);
    299  1.1  soren 			else
    300  1.1  soren 				hd44780_dr_write(sc, io->buf[i]);
    301  1.1  soren 		}
    302  1.1  soren 		if (i < io->len)
    303  1.1  soren 			io->len = i;
    304  1.1  soren 	} else {
    305  1.1  soren 		error = EINVAL;
    306  1.1  soren 	}
    307  1.1  soren 	return error;
    308  1.1  soren }
    309  1.1  soren 
    310  1.1  soren /*
    311  1.1  soren  * Write to the visible area of the display.
    312  1.1  soren  */
    313  1.1  soren void
    314  1.1  soren hd44780_ddram_redraw(sc, io)
    315  1.1  soren 	struct hd44780_chip *sc;
    316  1.1  soren 	struct hd44780_io *io;
    317  1.1  soren {
    318  1.1  soren 	u_int8_t i;
    319  1.1  soren 
    320  1.1  soren 	hd44780_ir_write(sc, cmd_clear());
    321  1.1  soren 	hd44780_ir_write(sc, cmd_rethome());
    322  1.1  soren 	for (i = 0; (i < io->len) && (i < sc->sc_rows); i++) {
    323  1.1  soren 		hd44780_dr_write(sc, io->buf[i]);
    324  1.1  soren 	}
    325  1.1  soren 	hd44780_ir_write(sc, cmd_ddramset(HD_ROW2_ADDR));
    326  1.1  soren 	for (; (i < io->len); i++)
    327  1.1  soren 		hd44780_dr_write(sc, io->buf[i]);
    328  1.1  soren }
    329  1.1  soren 
    330  1.3   joff void
    331  1.3   joff hd44780_busy_wait(sc)
    332  1.3   joff 	struct hd44780_chip *sc;
    333  1.3   joff {
    334  1.3   joff 	int nloops = 100;
    335  1.3   joff 
    336  1.3   joff 	if (sc->sc_flags & HD_TIMEDOUT)
    337  1.3   joff 		return;
    338  1.3   joff 
    339  1.3   joff 	while(nloops-- && (hd44780_ir_read(sc) & BUSY_FLAG) == BUSY_FLAG);
    340  1.3   joff 
    341  1.3   joff 	if (nloops == 0) {
    342  1.3   joff 		sc->sc_flags |= HD_TIMEDOUT;
    343  1.3   joff 		sc->sc_dev_ok = 0;
    344  1.3   joff 	}
    345  1.3   joff }
    346  1.3   joff 
    347  1.1  soren #if defined(HD44780_STD_WIDE)
    348  1.1  soren /*
    349  1.2   joff  * Standard 8-bit version of 'sc_writereg' (8-bit port, 8-bit access)
    350  1.1  soren  */
    351  1.1  soren void
    352  1.2   joff hd44780_writereg(sc, reg, cmd)
    353  1.2   joff 	struct hd44780_chip *sc;
    354  1.2   joff 	u_int32_t reg;
    355  1.1  soren 	u_int8_t cmd;
    356  1.1  soren {
    357  1.2   joff 	bus_space_tag_t iot = sc->sc_iot;
    358  1.2   joff 	bus_space_handle_t ioh;
    359  1.2   joff 
    360  1.3   joff 	if (sc->sc_dev_ok == 0)
    361  1.3   joff 		return;
    362  1.3   joff 
    363  1.2   joff 	if (reg == 0)
    364  1.2   joff 		ioh = sc->sc_ioir;
    365  1.2   joff 	else
    366  1.2   joff 		ioh = sc->sc_iodr;
    367  1.2   joff 
    368  1.1  soren 	bus_space_write_1(iot, ioh, 0x00, cmd);
    369  1.2   joff 	delay(HD_TIMEOUT_NORMAL);
    370  1.1  soren }
    371  1.1  soren 
    372  1.1  soren /*
    373  1.2   joff  * Standard 8-bit version of 'sc_readreg' (8-bit port, 8-bit access)
    374  1.1  soren  */
    375  1.1  soren u_int8_t
    376  1.2   joff hd44780_readreg(sc, reg)
    377  1.2   joff 	struct hd44780_chip *sc;
    378  1.2   joff 	u_int32_t reg;
    379  1.2   joff {
    380  1.2   joff 	bus_space_tag_t iot = sc->sc_iot;
    381  1.1  soren 	bus_space_handle_t ioh;
    382  1.2   joff 
    383  1.3   joff 	if (sc->sc_dev_ok == 0)
    384  1.3   joff 		return;
    385  1.3   joff 
    386  1.2   joff 	if (reg == 0)
    387  1.2   joff 		ioh = sc->sc_ioir;
    388  1.2   joff 	else
    389  1.2   joff 		ioh = sc->sc_iodr;
    390  1.2   joff 
    391  1.2   joff 	delay(HD_TIMEOUT_NORMAL);
    392  1.1  soren 	return bus_space_read_1(iot, ioh, 0x00);
    393  1.1  soren }
    394  1.1  soren #elif defined(HD44780_STD_SHORT)
    395  1.1  soren /*
    396  1.2   joff  * Standard 4-bit version of 'sc_writereg' (4-bit port, 8-bit access)
    397  1.1  soren  */
    398  1.1  soren void
    399  1.2   joff hd44780_writereg(sc, reg, cmd)
    400  1.2   joff 	struct hd44780_chip *sc;
    401  1.2   joff 	u_int32_t reg;
    402  1.1  soren 	u_int8_t cmd;
    403  1.1  soren {
    404  1.2   joff 	bus_space_tag_t iot = sc->sc_iot;
    405  1.2   joff 	bus_space_handle_t ioh;
    406  1.2   joff 
    407  1.3   joff 	if (sc->sc_dev_ok == 0)
    408  1.3   joff 		return;
    409  1.3   joff 
    410  1.2   joff 	if (reg == 0)
    411  1.2   joff 		ioh = sc->sc_ioir;
    412  1.2   joff 	else
    413  1.2   joff 		ioh = sc->sc_iodr;
    414  1.1  soren 
    415  1.1  soren 	bus_space_write_1(iot, ioh, 0x00, hi_bits(cmd));
    416  1.2   joff 	if (sc->sc_flags & HD_UP)
    417  1.2   joff 		bus_space_write_1(iot, ioh, 0x00, lo_bits(cmd));
    418  1.2   joff 	delay(HD_TIMEOUT_NORMAL);
    419  1.1  soren }
    420  1.1  soren 
    421  1.1  soren /*
    422  1.2   joff  * Standard 4-bit version of 'sc_readreg' (4-bit port, 8-bit access)
    423  1.1  soren  */
    424  1.1  soren u_int8_t
    425  1.2   joff hd44780_readreg(sc, reg)
    426  1.2   joff 	struct hd44780_chip *sc;
    427  1.2   joff 	u_int32_t reg;
    428  1.2   joff {
    429  1.2   joff 	bus_space_tag_t iot = sc->sc_iot;
    430  1.1  soren 	bus_space_handle_t ioh;
    431  1.2   joff 	u_int8_t rd, dat;
    432  1.2   joff 
    433  1.3   joff 	if (sc->sc_dev_ok == 0)
    434  1.3   joff 		return;
    435  1.3   joff 
    436  1.2   joff 	if (reg == 0)
    437  1.2   joff 		ioh = sc->sc_ioir;
    438  1.2   joff 	else
    439  1.2   joff 		ioh = sc->sc_iodr;
    440  1.1  soren 
    441  1.1  soren 	rd = bus_space_read_1(iot, ioh, 0x00);
    442  1.1  soren 	dat = (rd & 0x0f) << 4;
    443  1.1  soren 	rd = bus_space_read_1(iot, ioh, 0x00);
    444  1.1  soren 	return (dat | (rd & 0x0f));
    445  1.1  soren }
    446  1.1  soren #endif
    447