From 02e79f9fb1c7c7290198cfb32dfdc2f2a3368013 Mon Sep 17 00:00:00 2001 From: joff Date: Sun, 14 Aug 2005 02:56:06 +0000 Subject: [PATCH] 4-line HD44780 LCD display support. Work needed for the NetBSD toaster port. The HD44780 actually doesn't support 4 lines, but the 4 line displays use two chips, one for the top two lines and one for the bottom two lines. The chips share the databus, register-select, and write signals but have separate enable signals. --- sys/dev/ic/hd44780_subr.c | 210 ++++++++++++++++++++++++-------------- sys/dev/ic/hd44780var.h | 42 +++++--- 2 files changed, 156 insertions(+), 96 deletions(-) diff --git a/sys/dev/ic/hd44780_subr.c b/sys/dev/ic/hd44780_subr.c index d25502b79212..f2aa6288fef6 100644 --- a/sys/dev/ic/hd44780_subr.c +++ b/sys/dev/ic/hd44780_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: hd44780_subr.c,v 1.6 2005/02/27 00:27:01 perry Exp $ */ +/* $NetBSD: hd44780_subr.c,v 1.7 2005/08/14 02:56:06 joff Exp $ */ /* * Copyright (c) 2002 Dennis I. Chernoivanov @@ -32,7 +32,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: hd44780_subr.c,v 1.6 2005/02/27 00:27:01 perry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hd44780_subr.c,v 1.7 2005/08/14 02:56:06 joff Exp $"); #include #include @@ -57,15 +57,14 @@ __KERNEL_RCSID(0, "$NetBSD: hd44780_subr.c,v 1.6 2005/02/27 00:27:01 perry Exp $ #define COORD_TO_IDX(x, y) ((y) * sc->sc_cols + (x)) #define COORD_TO_DADDR(x, y) ((y) * HD_ROW2_ADDR + (x)) -#define IDX_TO_ROW(idx) (((idx) >= sc->sc_cols) ? 1 : 0) -#define IDX_TO_COL(idx) (((idx) >= sc->sc_cols) ? \ - ((idx) - sc->sc_cols) : (idx)) -#define IDX_TO_DDADDR(idx) ((IDX_TO_ROW((idx)) == 1) ? \ - (HD_ROW2_ADDR + IDX_TO_COL((idx))) : \ - (IDX_TO_COL((idx)))) -#define DADDR_TO_ROW(daddr) (((daddr) >= HD_ROW2_ADDR) ? 1 : 0) -#define DADDR_TO_COL(daddr) ((DADDR_TO_ROW((daddr)) == 1) ? \ - ((daddr) - HD_ROW2_ADDR) : (daddr)) +#define IDX_TO_ROW(idx) ((idx) / sc->sc_cols) +#define IDX_TO_COL(idx) ((idx) % sc->sc_cols) +#define IDX_TO_DADDR(idx) (IDX_TO_ROW((idx)) * HD_ROW2_ADDR + \ + IDX_TO_COL((idx))) +#define DADDR_TO_ROW(daddr) ((daddr) / HD_ROW2_ADDR) +#define DADDR_TO_COL(daddr) ((daddr) % HD_ROW2_ADDR) +#define DADDR_TO_CHIPDADDR(daddr) ((daddr) % (HD_ROW2_ADDR * 2)) +#define DADDR_TO_CHIPNO(daddr) ((daddr) / (HD_ROW2_ADDR * 2)) static void hlcd_cursor(void *, int, int, int); static int hlcd_mapchar(void *, int, unsigned int *); @@ -142,7 +141,7 @@ hlcd_putchar(id, row, col, c, attr) struct hlcd_screen *hdscr = id; c &= 0xff; - if (row > 0 && (hdscr->hlcd_sc->sc_flags & HD_MULTILINE)) + if (row > 0 && (hdscr->hlcd_sc->sc_flags & (HD_MULTILINE|HD_MULTICHIP))) hdscr->image[hdscr->hlcd_sc->sc_cols * row + col] = c; else hdscr->image[col] = c; @@ -161,7 +160,7 @@ hlcd_copycols(id, row, srccol, dstcol, ncols) if ((dstcol + ncols - 1) > hdscr->hlcd_sc->sc_cols) ncols = hdscr->hlcd_sc->sc_cols - srccol; - if (row > 0 && (hdscr->hlcd_sc->sc_flags & HD_MULTILINE)) + if (row > 0 && (hdscr->hlcd_sc->sc_flags & (HD_MULTILINE|HD_MULTICHIP))) bcopy(&hdscr->image[hdscr->hlcd_sc->sc_cols * row + srccol], &hdscr->image[hdscr->hlcd_sc->sc_cols * row + dstcol], ncols); else @@ -183,7 +182,7 @@ hlcd_erasecols(id, row, startcol, ncols, fillattr) if ((startcol + ncols) > hdscr->hlcd_sc->sc_cols) ncols = hdscr->hlcd_sc->sc_cols - startcol; - if (row > 0 && (hdscr->hlcd_sc->sc_flags & HD_MULTILINE)) + if (row > 0 && (hdscr->hlcd_sc->sc_flags & (HD_MULTILINE|HD_MULTICHIP))) memset(&hdscr->image[hdscr->hlcd_sc->sc_cols * row + startcol], ' ', ncols); else @@ -199,7 +198,7 @@ hlcd_copyrows(id, srcrow, dstrow, nrows) struct hlcd_screen *hdscr = id; int ncols = hdscr->hlcd_sc->sc_cols; - if (!(hdscr->hlcd_sc->sc_flags & HD_MULTILINE)) + if (!(hdscr->hlcd_sc->sc_flags & (HD_MULTILINE|HD_MULTICHIP))) return; bcopy(&hdscr->image[srcrow * ncols], &hdscr->image[dstrow * ncols], nrows * ncols); @@ -307,14 +306,16 @@ hlcd_updatechar(sc, daddr, c) struct hd44780_chip *sc; int daddr, c; { - int curdaddr; + int curdaddr, en, chipdaddr; curdaddr = COORD_TO_DADDR(sc->sc_screen.hlcd_curx, sc->sc_screen.hlcd_cury); + en = DADDR_TO_CHIPNO(daddr); + chipdaddr = DADDR_TO_CHIPDADDR(daddr); if (daddr != curdaddr) - hd44780_ir_write(sc, cmd_ddramset(daddr)); + hd44780_ir_write(sc, en, cmd_ddramset(chipdaddr)); - hd44780_dr_write(sc, c); + hd44780_dr_write(sc, en, c); daddr++; sc->sc_screen.hlcd_curx = DADDR_TO_COL(daddr); @@ -327,6 +328,7 @@ hlcd_redraw(arg) { struct hd44780_chip *sc = arg; int len, crsridx, startidx, x, y; + int old_en, new_en; u_char *img, *curimg; if (sc->sc_curscr == NULL) @@ -337,13 +339,20 @@ hlcd_redraw(arg) else len = sc->sc_cols; + if (sc->sc_flags & HD_MULTICHIP) + len = len * 2; + + x = sc->sc_screen.hlcd_curx; + y = sc->sc_screen.hlcd_cury; + old_en = DADDR_TO_CHIPNO(COORD_TO_DADDR(x, y)); + img = sc->sc_screen.image; curimg = sc->sc_curscr->image; startidx = crsridx = COORD_TO_IDX(sc->sc_screen.hlcd_curx, sc->sc_screen.hlcd_cury); do { if (img[crsridx] != curimg[crsridx]) { - hlcd_updatechar(sc, IDX_TO_DDADDR(crsridx), + hlcd_updatechar(sc, IDX_TO_DADDR(crsridx), curimg[crsridx]); img[crsridx] = curimg[crsridx]; } @@ -352,19 +361,33 @@ hlcd_redraw(arg) crsridx = 0; } while (crsridx != startidx); + x = sc->sc_curscr->hlcd_curx; + y = sc->sc_curscr->hlcd_cury; + new_en = DADDR_TO_CHIPNO(COORD_TO_DADDR(x, y)); + if (sc->sc_screen.hlcd_curx != sc->sc_curscr->hlcd_curx || sc->sc_screen.hlcd_cury != sc->sc_curscr->hlcd_cury) { + x = sc->sc_screen.hlcd_curx = sc->sc_curscr->hlcd_curx; y = sc->sc_screen.hlcd_cury = sc->sc_curscr->hlcd_cury; - hd44780_ir_write(sc, cmd_ddramset(COORD_TO_DADDR(x, y))); + + hd44780_ir_write(sc, new_en, cmd_ddramset( + DADDR_TO_CHIPDADDR(COORD_TO_DADDR(x, y)))); + + } + + /* visible cursor switched to other chip */ + if (old_en != new_en && sc->sc_screen.hlcd_curon) { + hd44780_ir_write(sc, old_en, cmd_dispctl(1, 0, 0)); + hd44780_ir_write(sc, new_en, cmd_dispctl(1, 1, 1)); } if (sc->sc_screen.hlcd_curon != sc->sc_curscr->hlcd_curon) { sc->sc_screen.hlcd_curon = sc->sc_curscr->hlcd_curon; if (sc->sc_screen.hlcd_curon) - hd44780_ir_write(sc, cmd_dispctl(1, 1, 1)); + hd44780_ir_write(sc, new_en, cmd_dispctl(1, 1, 1)); else - hd44780_ir_write(sc, cmd_dispctl(1, 0, 0)); + hd44780_ir_write(sc, new_en, cmd_dispctl(1, 0, 0)); } callout_schedule(&sc->redraw, 1); @@ -403,26 +426,39 @@ hd44780_attach_subr(sc) sc->sc_screen.image = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK); memset(sc->sc_screen.image, ' ', PAGE_SIZE); sc->sc_curscr = NULL; + sc->sc_curchip = 0; callout_init(&sc->redraw); callout_setfunc(&sc->redraw, hlcd_redraw, sc); } +int hd44780_init(sc) + struct hd44780_chip *sc; +{ + int ret; + + ret = hd44780_chipinit(sc, 0); + if (ret != 0 || !(sc->sc_flags & HD_MULTICHIP)) return ret; + else return hd44780_chipinit(sc, 1); +} + /* * Initialize 4-bit or 8-bit connected device. */ int -hd44780_init(sc) +hd44780_chipinit(sc, en) struct hd44780_chip *sc; + u_int32_t en; { u_int8_t cmd, dat; sc->sc_flags &= ~(HD_TIMEDOUT|HD_UP); sc->sc_dev_ok = 1; + cmd = cmd_init(sc->sc_flags & HD_8BIT); - hd44780_ir_write(sc, cmd); + hd44780_ir_write(sc, en, cmd); delay(HD_TIMEOUT_LONG); - hd44780_ir_write(sc, cmd); - hd44780_ir_write(sc, cmd); + hd44780_ir_write(sc, en, cmd); + hd44780_ir_write(sc, en, cmd); cmd = cmd_funcset( sc->sc_flags & HD_8BIT, @@ -430,14 +466,14 @@ hd44780_init(sc) sc->sc_flags & HD_BIGFONT); if ((sc->sc_flags & HD_8BIT) == 0) - hd44780_ir_write(sc, cmd); + hd44780_ir_write(sc, en, cmd); sc->sc_flags |= HD_UP; - hd44780_ir_write(sc, cmd); - hd44780_ir_write(sc, cmd_dispctl(0, 0, 0)); - hd44780_ir_write(sc, cmd_clear()); - hd44780_ir_write(sc, cmd_modset(1, 0)); + hd44780_ir_write(sc, en, cmd); + hd44780_ir_write(sc, en, cmd_dispctl(0, 0, 0)); + hd44780_ir_write(sc, en, cmd_clear()); + hd44780_ir_write(sc, en, cmd_modset(1, 0)); if (sc->sc_flags & HD_TIMEDOUT) { sc->sc_flags &= ~HD_UP; @@ -445,19 +481,19 @@ hd44780_init(sc) } /* Turn display on and clear it. */ - hd44780_ir_write(sc, cmd_clear()); - hd44780_ir_write(sc, cmd_dispctl(1, 0, 0)); + hd44780_ir_write(sc, en, cmd_clear()); + hd44780_ir_write(sc, en, cmd_dispctl(1, 0, 0)); /* Attempt a simple probe for presence */ - hd44780_ir_write(sc, cmd_ddramset(0x5)); - hd44780_ir_write(sc, cmd_shift(0, 1)); - hd44780_busy_wait(sc); - if ((dat = hd44780_ir_read(sc) & 0x7f) != 0x6) { + hd44780_ir_write(sc, en, cmd_ddramset(0x5)); + hd44780_ir_write(sc, en, cmd_shift(0, 1)); + hd44780_busy_wait(sc, en); + if ((dat = hd44780_ir_read(sc, en) & 0x7f) != 0x6) { sc->sc_dev_ok = 0; sc->sc_flags &= ~HD_UP; return EIO; } - hd44780_ir_write(sc, cmd_ddramset(0)); + hd44780_ir_write(sc, en, cmd_ddramset(0)); return 0; } @@ -473,6 +509,7 @@ hd44780_ioctl_subr(sc, cmd, data) { u_int8_t tmp; int error = 0; + u_int32_t en = sc->sc_curchip; #define hd44780_io() ((struct hd44780_io *)data) #define hd44780_info() ((struct hd44780_info*)data) @@ -481,22 +518,22 @@ hd44780_ioctl_subr(sc, cmd, data) switch (cmd) { /* Clear the LCD. */ case HLCD_CLEAR: - hd44780_ir_write(sc, cmd_clear()); + hd44780_ir_write(sc, en, cmd_clear()); break; /* Move the cursor one position to the left. */ case HLCD_CURSOR_LEFT: - hd44780_ir_write(sc, cmd_shift(0, 0)); + hd44780_ir_write(sc, en, cmd_shift(0, 0)); break; /* Move the cursor one position to the right. */ case HLCD_CURSOR_RIGHT: - hd44780_ir_write(sc, cmd_shift(0, 1)); + hd44780_ir_write(sc, en, cmd_shift(0, 1)); break; /* Control the LCD. */ case HLCD_DISPCTL: - hd44780_ir_write(sc, cmd_dispctl( + hd44780_ir_write(sc, en, cmd_dispctl( hd44780_ctrl()->display_on, hd44780_ctrl()->cursor_on, hd44780_ctrl()->blink_on)); @@ -506,6 +543,8 @@ hd44780_ioctl_subr(sc, cmd, data) case HLCD_GET_INFO: hd44780_info()->lines = (sc->sc_flags & HD_MULTILINE) ? 2 : 1; + if (sc->sc_flags & HD_MULTICHIP) + hd44780_info()->lines *= 2; hd44780_info()->phys_rows = sc->sc_cols; hd44780_info()->virt_rows = sc->sc_vcols; hd44780_info()->is_wide = sc->sc_flags & HD_8BIT; @@ -521,64 +560,74 @@ hd44780_ioctl_subr(sc, cmd, data) /* Get the current cursor position. */ case HLCD_GET_CURSOR_POS: - hd44780_io()->dat = (hd44780_ir_read(sc) & 0x7f); + hd44780_io()->dat = (hd44780_ir_read(sc, en) & 0x7f); break; /* Set the cursor position. */ case HLCD_SET_CURSOR_POS: - hd44780_ir_write(sc, cmd_ddramset(hd44780_io()->dat)); + hd44780_ir_write(sc, en, cmd_ddramset(hd44780_io()->dat)); break; /* Get the value at the current cursor position. */ case HLCD_GETC: - tmp = (hd44780_ir_read(sc) & 0x7f); - hd44780_ir_write(sc, cmd_ddramset(tmp)); - hd44780_io()->dat = hd44780_dr_read(sc); + tmp = (hd44780_ir_read(sc, en) & 0x7f); + hd44780_ir_write(sc, en, cmd_ddramset(tmp)); + hd44780_io()->dat = hd44780_dr_read(sc, en); break; /* Set the character at the cursor position + advance cursor. */ case HLCD_PUTC: - hd44780_dr_write(sc, hd44780_io()->dat); + hd44780_dr_write(sc, en, hd44780_io()->dat); break; /* Shift display left. */ case HLCD_SHIFT_LEFT: - hd44780_ir_write(sc, cmd_shift(1, 0)); + hd44780_ir_write(sc, en, cmd_shift(1, 0)); break; /* Shift display right. */ case HLCD_SHIFT_RIGHT: - hd44780_ir_write(sc, cmd_shift(1, 1)); + hd44780_ir_write(sc, en, cmd_shift(1, 1)); break; /* Return home. */ case HLCD_HOME: - hd44780_ir_write(sc, cmd_rethome()); + hd44780_ir_write(sc, en, cmd_rethome()); break; /* Write a string to the LCD virtual area. */ case HLCD_WRITE: - error = hd44780_ddram_io(sc, hd44780_io(), HD_DDRAM_WRITE); + error = hd44780_ddram_io(sc, en, hd44780_io(), HD_DDRAM_WRITE); break; /* Read LCD virtual area. */ case HLCD_READ: - error = hd44780_ddram_io(sc, hd44780_io(), HD_DDRAM_READ); + error = hd44780_ddram_io(sc, en, hd44780_io(), HD_DDRAM_READ); break; /* Write to the LCD visible area. */ case HLCD_REDRAW: - hd44780_ddram_redraw(sc, hd44780_io()); + hd44780_ddram_redraw(sc, en, hd44780_io()); break; /* Write raw instruction. */ case HLCD_WRITE_INST: - hd44780_ir_write(sc, hd44780_io()->dat); + hd44780_ir_write(sc, en, hd44780_io()->dat); break; /* Write raw data. */ case HLCD_WRITE_DATA: - hd44780_dr_write(sc, hd44780_io()->dat); + hd44780_dr_write(sc, en, hd44780_io()->dat); + break; + + /* Get current chip 0 or 1 (top or bottom) */ + case HLCD_GET_CHIPNO: + *(u_int8_t *)data = sc->sc_curchip; + break; + + /* Set current chip 0 or 1 (top or bottom) */ + case HLCD_SET_CHIPNO: + sc->sc_curchip = *(u_int8_t *)data; break; default: @@ -595,8 +644,9 @@ hd44780_ioctl_subr(sc, cmd, data) * Read/write particular area of the LCD screen. */ int -hd44780_ddram_io(sc, io, dir) +hd44780_ddram_io(sc, en, io, dir) struct hd44780_chip *sc; + u_int32_t en; struct hd44780_io *io; u_char dir; { @@ -610,11 +660,11 @@ hd44780_ddram_io(sc, io, dir) hi = HD_ROW1_ADDR + sc->sc_vcols; addr = HD_ROW1_ADDR + io->dat; for (; (addr < hi) && (i < io->len); addr++, i++) { - hd44780_ir_write(sc, cmd_ddramset(addr)); + hd44780_ir_write(sc, en, cmd_ddramset(addr)); if (dir == HD_DDRAM_READ) - io->buf[i] = hd44780_dr_read(sc); + io->buf[i] = hd44780_dr_read(sc, en); else - hd44780_dr_write(sc, io->buf[i]); + hd44780_dr_write(sc, en, io->buf[i]); } } if (io->dat < 2 * sc->sc_vcols) { @@ -624,11 +674,11 @@ hd44780_ddram_io(sc, io, dir) else addr = HD_ROW2_ADDR; for (; (addr < hi) && (i < io->len); addr++, i++) { - hd44780_ir_write(sc, cmd_ddramset(addr)); + hd44780_ir_write(sc, en, cmd_ddramset(addr)); if (dir == HD_DDRAM_READ) - io->buf[i] = hd44780_dr_read(sc); + io->buf[i] = hd44780_dr_read(sc, en); else - hd44780_dr_write(sc, io->buf[i]); + hd44780_dr_write(sc, en, io->buf[i]); } if (i < io->len) io->len = i; @@ -642,32 +692,34 @@ hd44780_ddram_io(sc, io, dir) * Write to the visible area of the display. */ void -hd44780_ddram_redraw(sc, io) +hd44780_ddram_redraw(sc, en, io) struct hd44780_chip *sc; + u_int32_t en; struct hd44780_io *io; { u_int8_t i; - hd44780_ir_write(sc, cmd_clear()); - hd44780_ir_write(sc, cmd_rethome()); + hd44780_ir_write(sc, en, cmd_clear()); + hd44780_ir_write(sc, en, cmd_rethome()); for (i = 0; (i < io->len) && (i < sc->sc_cols); i++) { - hd44780_dr_write(sc, io->buf[i]); + hd44780_dr_write(sc, en, io->buf[i]); } - hd44780_ir_write(sc, cmd_ddramset(HD_ROW2_ADDR)); + hd44780_ir_write(sc, en, cmd_ddramset(HD_ROW2_ADDR)); for (; (i < io->len); i++) - hd44780_dr_write(sc, io->buf[i]); + hd44780_dr_write(sc, en, io->buf[i]); } void -hd44780_busy_wait(sc) +hd44780_busy_wait(sc, en) struct hd44780_chip *sc; + u_int32_t en; { int nloops = 100; if (sc->sc_flags & HD_TIMEDOUT) return; - while(nloops-- && (hd44780_ir_read(sc) & BUSY_FLAG) == BUSY_FLAG); + while(nloops-- && (hd44780_ir_read(sc, en) & BUSY_FLAG) == BUSY_FLAG); if (nloops == 0) { sc->sc_flags |= HD_TIMEDOUT; @@ -680,9 +732,9 @@ hd44780_busy_wait(sc) * Standard 8-bit version of 'sc_writereg' (8-bit port, 8-bit access) */ void -hd44780_writereg(sc, reg, cmd) +hd44780_writereg(sc, en, reg, cmd) struct hd44780_chip *sc; - u_int32_t reg; + u_int32_t en, reg; u_int8_t cmd; { bus_space_tag_t iot = sc->sc_iot; @@ -704,9 +756,9 @@ hd44780_writereg(sc, reg, cmd) * Standard 8-bit version of 'sc_readreg' (8-bit port, 8-bit access) */ u_int8_t -hd44780_readreg(sc, reg) +hd44780_readreg(sc, en, reg) struct hd44780_chip *sc; - u_int32_t reg; + u_int32_t en, reg; { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh; @@ -727,9 +779,9 @@ hd44780_readreg(sc, reg) * Standard 4-bit version of 'sc_writereg' (4-bit port, 8-bit access) */ void -hd44780_writereg(sc, reg, cmd) +hd44780_writereg(sc, en, reg, cmd) struct hd44780_chip *sc; - u_int32_t reg; + u_int32_t en, reg; u_int8_t cmd; { bus_space_tag_t iot = sc->sc_iot; @@ -753,9 +805,9 @@ hd44780_writereg(sc, reg, cmd) * Standard 4-bit version of 'sc_readreg' (4-bit port, 8-bit access) */ u_int8_t -hd44780_readreg(sc, reg) +hd44780_readreg(sc, en, reg) struct hd44780_chip *sc; - u_int32_t reg; + u_int32_t en, reg; { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh; diff --git a/sys/dev/ic/hd44780var.h b/sys/dev/ic/hd44780var.h index e0b6707060fb..dab866275be3 100644 --- a/sys/dev/ic/hd44780var.h +++ b/sys/dev/ic/hd44780var.h @@ -1,4 +1,4 @@ -/* $NetBSD: hd44780var.h,v 1.2 2005/02/04 05:58:44 joff Exp $ */ +/* $NetBSD: hd44780var.h,v 1.3 2005/08/14 02:56:06 joff Exp $ */ /* * Copyright (c) 2002 Dennis I. Chernoivanov @@ -49,14 +49,18 @@ #define HLCD_WRITE_INST _IOW('h', 16, struct hd44780_io) #define HLCD_WRITE_DATA _IOW('h', 17, struct hd44780_io) #define HLCD_GET_INFO _IOR('h', 18, struct hd44780_info) +#define HLCD_GET_CHIPNO _IOR('h', 19, u_int8_t) +#define HLCD_SET_CHIPNO _IOW('h', 20, u_int8_t) struct hd44780_dispctl { + u_int8_t chip; u_char display_on:1, blink_on:1, cursor_on:1; }; struct hd44780_io { + u_int8_t chip; u_int8_t dat; u_int8_t len; u_int8_t buf[HD_MAX_CHARS]; @@ -90,11 +94,13 @@ struct hd44780_chip { #define HD_KEYPAD 0x08 /* if set, keypad is connected */ #define HD_UP 0x10 /* if set, lcd has been initialized */ #define HD_TIMEDOUT 0x20 /* lcd has recently stopped talking */ +#define HD_MULTICHIP 0x40 /* two HD44780 controllers (4-line) */ u_char sc_flags; u_char sc_cols; /* visible columns */ u_char sc_vcols; /* virtual columns (normally 40) */ u_char sc_dev_ok; + u_char sc_curchip; bus_space_tag_t sc_iot; @@ -107,38 +113,40 @@ struct hd44780_chip { struct callout redraw; /* wsdisplay refresh/redraw timer */ /* Generic write/read byte entries. */ - void (* sc_writereg)(struct hd44780_chip *, u_int32_t, u_int8_t); - u_int8_t (* sc_readreg)(struct hd44780_chip *, u_int32_t); + void (* sc_writereg)(struct hd44780_chip *, u_int32_t, u_int32_t, + u_int8_t); + u_int8_t (* sc_readreg)(struct hd44780_chip *, u_int32_t, u_int32_t); }; -#define hd44780_ir_write(sc, dat) \ +#define hd44780_ir_write(sc, en, dat) \ do { \ - hd44780_busy_wait(sc); \ - (sc)->sc_writereg((sc), 0, (dat)); \ + hd44780_busy_wait(sc, (en)); \ + (sc)->sc_writereg((sc), (en), 0, (dat)); \ } while(0) -#define hd44780_ir_read(sc) \ - (sc)->sc_readreg((sc), 0) +#define hd44780_ir_read(sc, en) \ + (sc)->sc_readreg((sc), (en), 0) -#define hd44780_dr_write(sc, dat) \ - (sc)->sc_writereg((sc), 1, (dat)) +#define hd44780_dr_write(sc, en, dat) \ + (sc)->sc_writereg((sc), (en), 1, (dat)) -#define hd44780_dr_read(sc) \ - (sc)->sc_readreg((sc), 1) +#define hd44780_dr_read(sc, en) \ + (sc)->sc_readreg((sc), (en), 1) void hd44780_attach_subr(struct hd44780_chip *); -void hd44780_busy_wait(struct hd44780_chip *); +void hd44780_busy_wait(struct hd44780_chip *, u_int32_t); int hd44780_init(struct hd44780_chip *); +int hd44780_chipinit(struct hd44780_chip *, u_int32_t); int hd44780_ioctl_subr(struct hd44780_chip *, u_long, caddr_t); -void hd44780_ddram_redraw(struct hd44780_chip *, struct hd44780_io *); +void hd44780_ddram_redraw(struct hd44780_chip *, u_int32_t, struct hd44780_io *); #define HD_DDRAM_READ 0x0 #define HD_DDRAM_WRITE 0x1 -int hd44780_ddram_io(struct hd44780_chip *, struct hd44780_io *, u_char); +int hd44780_ddram_io(struct hd44780_chip *, u_int32_t, struct hd44780_io *, u_char); #if defined(HD44780_STD_WIDE) || defined(HD44780_STD_SHORT) -void hd44780_writereg(struct hd44780_chip *, u_int32_t, u_int8_t); -u_int8_t hd44780_readreg(struct hd44780_chip *, u_int32_t); +void hd44780_writereg(struct hd44780_chip *, u_int32_t, u_int32_t, u_int8_t); +u_int8_t hd44780_readreg(struct hd44780_chip *, u_int32_t, u_int32_t); #endif #endif /* _KERNEL */