1 /* $OpenBSD: lcd.c,v 1.5 2020/03/06 01:45:32 cheloha Exp $ */ 2 3 /* 4 * Copyright (c) 2007 Mark Kettenis 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/device.h> 21 #include <sys/kernel.h> 22 #include <sys/systm.h> 23 #include <sys/timeout.h> 24 25 #include <machine/autoconf.h> 26 #include <machine/bus.h> 27 #include <machine/cpu.h> 28 #include <machine/pdc.h> 29 30 #define LCD_CLS 0x01 31 #define LCD_HOME 0x02 32 #define LCD_LOCATE(X, Y) (((Y) & 1 ? 0xc0 : 0x80) | ((X) & 0x0f)) 33 34 struct lcd_softc { 35 struct device sc_dv; 36 37 bus_space_tag_t sc_iot; 38 bus_space_handle_t sc_cmdh, sc_datah; 39 40 u_int sc_delay; 41 u_int8_t sc_heartbeat[3]; 42 43 struct timeout sc_to; 44 int sc_on; 45 struct blink_led sc_blink; 46 }; 47 48 int lcd_match(struct device *, void *, void *); 49 void lcd_attach(struct device *, struct device *, void *); 50 51 struct cfattach lcd_ca = { 52 sizeof(struct lcd_softc), lcd_match, lcd_attach 53 }; 54 55 struct cfdriver lcd_cd = { 56 NULL, "lcd", DV_DULL 57 }; 58 59 void lcd_mountroot(struct device *); 60 void lcd_write(struct lcd_softc *, const char *); 61 void lcd_blink(void *, int); 62 void lcd_blink_finish(void *); 63 64 int 65 lcd_match(struct device *parent, void *match, void *aux) 66 { 67 struct confargs *ca = aux; 68 69 if (strcmp(ca->ca_name, "lcd") == 0) 70 return (1); 71 72 return (0); 73 } 74 75 void 76 lcd_attach(struct device *parent, struct device *self, void *aux) 77 { 78 struct lcd_softc *sc = (struct lcd_softc *)self; 79 struct confargs *ca = aux; 80 struct pdc_chassis_lcd *pdc_lcd = (void *)ca->ca_pdc_iodc_read; 81 int i; 82 83 sc->sc_iot = ca->ca_iot; 84 if (bus_space_map(sc->sc_iot, pdc_lcd->cmd_addr, 85 1, 0, &sc->sc_cmdh)) { 86 printf(": cannot map cmd register\n"); 87 return; 88 } 89 90 if (bus_space_map(sc->sc_iot, pdc_lcd->data_addr, 91 1, 0, &sc->sc_datah)) { 92 printf(": cannot map data register\n"); 93 bus_space_unmap(sc->sc_iot, sc->sc_cmdh, 1); 94 return; 95 } 96 97 printf(": model %d\n", pdc_lcd->model); 98 99 sc->sc_delay = pdc_lcd->delay; 100 for (i = 0; i < 3; i++) 101 sc->sc_heartbeat[i] = pdc_lcd->heartbeat[i]; 102 103 timeout_set(&sc->sc_to, lcd_blink_finish, sc); 104 105 sc->sc_blink.bl_func = lcd_blink; 106 sc->sc_blink.bl_arg = sc; 107 blink_led_register(&sc->sc_blink); 108 109 config_mountroot(self, lcd_mountroot); 110 } 111 112 void 113 lcd_mountroot(struct device *self) 114 { 115 struct lcd_softc *sc = (struct lcd_softc *)self; 116 117 bus_space_write_1(sc->sc_iot, sc->sc_cmdh, 0, LCD_CLS); 118 delay(100 * sc->sc_delay); 119 120 bus_space_write_1(sc->sc_iot, sc->sc_cmdh, 0, LCD_LOCATE(0, 0)); 121 delay(sc->sc_delay); 122 lcd_write(sc, "OpenBSD/" MACHINE); 123 } 124 125 void 126 lcd_write(struct lcd_softc *sc, const char *str) 127 { 128 while (*str) { 129 bus_space_write_1(sc->sc_iot, sc->sc_datah, 0, *str++); 130 delay(sc->sc_delay); 131 } 132 } 133 134 void 135 lcd_blink(void *v, int on) 136 { 137 struct lcd_softc *sc = v; 138 139 sc->sc_on = on; 140 bus_space_write_1(sc->sc_iot, sc->sc_cmdh, 0, sc->sc_heartbeat[0]); 141 timeout_add_usec(&sc->sc_to, sc->sc_delay); 142 } 143 144 void 145 lcd_blink_finish(void *v) 146 { 147 struct lcd_softc *sc = v; 148 u_int8_t data; 149 150 if (sc->sc_on) 151 data = sc->sc_heartbeat[1]; 152 else 153 data = sc->sc_heartbeat[2]; 154 155 bus_space_write_1(sc->sc_iot, sc->sc_datah, 0, data); 156 } 157