1 /* $OpenBSD: ppm.c,v 1.1 2006/06/02 04:46:01 jason Exp $ */ 2 3 /* 4 * Copyright (c) 2006 Jason L. Wright (jason@thought.net) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/types.h> 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/device.h> 33 34 #include <machine/bus.h> 35 #include <machine/autoconf.h> 36 #include <machine/openfirm.h> 37 38 #include <sparc64/dev/ebusreg.h> 39 #include <sparc64/dev/ebusvar.h> 40 41 #define BBC_GPIOBANK_INDEX 0x0 42 #define BBC_GPIOBANK_DATA 0x1 43 44 #define BBC_GPIO_PORT1_DATA 0x0 45 #define BBC_GPIO_PORT2_DATA 0x4 46 47 #define GPIO_P2D_LED 0x2 48 49 struct ppm_softc { 50 struct device sc_dv; 51 bus_space_tag_t sc_iot; 52 bus_space_handle_t sc_estarh; 53 bus_space_handle_t sc_rioh; 54 bus_space_handle_t sc_gpiobankh; 55 bus_space_handle_t sc_gpioh; 56 struct blink_led sc_blink; 57 }; 58 59 int ppm_match(struct device *, void *, void *); 60 void ppm_attach(struct device *, struct device *, void *); 61 62 struct cfattach ppm_ca = { 63 sizeof(struct ppm_softc), ppm_match, ppm_attach 64 }; 65 66 struct cfdriver ppm_cd = { 67 NULL, "ppm", DV_DULL 68 }; 69 70 void ppm_led_blink(void *, int); 71 72 int 73 ppm_match(struct device *parent, void *match, void *aux) 74 { 75 struct ebus_attach_args *ea = aux; 76 77 if (strcmp(ea->ea_name, "ppm")) 78 return (0); 79 return (1); 80 } 81 82 void 83 ppm_attach(struct device *parent, struct device *self, void *aux) 84 { 85 struct ppm_softc *sc = (void *)self; 86 struct ebus_attach_args *ea = aux; 87 u_int8_t reg; 88 89 sc->sc_iot = ea->ea_memtag; 90 91 if (ea->ea_nregs < 4) { 92 printf(": need %d regs\n", 4); 93 return; 94 } 95 96 #if 0 97 if (ebus_bus_map(sc->sc_iot, 0, 98 EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, 99 0, 0, &sc->sc_estarh)) { 100 printf(": failed to map estar\n"); 101 return; 102 } 103 #endif 104 #if 0 105 if (ebus_bus_map(sc->sc_iot, 0, 106 EBUS_PADDR_FROM_REG(&ea->ea_regs[1]), ea->ea_regs[1].size, 107 0, 0, &sc->sc_rioh)) { 108 printf(": failed to map riohr\n"); 109 return; 110 } 111 #endif 112 113 if (ebus_bus_map(sc->sc_iot, 0, 114 EBUS_PADDR_FROM_REG(&ea->ea_regs[2]), ea->ea_regs[2].size, 115 0, 0, &sc->sc_gpiobankh)) { 116 printf(": failed to map gpiobank\n"); 117 return; 118 } 119 120 if (ebus_bus_map(sc->sc_iot, 0, 121 EBUS_PADDR_FROM_REG(&ea->ea_regs[3]), ea->ea_regs[3].size, 122 0, 0, &sc->sc_gpioh)) { 123 printf(": failed to map gpio\n"); 124 return; 125 } 126 127 bus_space_write_1(sc->sc_iot, sc->sc_gpiobankh, 128 BBC_GPIOBANK_INDEX, 0x22); 129 bus_space_read_1(sc->sc_iot, sc->sc_gpiobankh, BBC_GPIOBANK_INDEX); 130 reg = bus_space_read_1(sc->sc_iot, sc->sc_gpiobankh, BBC_GPIOBANK_DATA); 131 reg &= 0x7f; 132 bus_space_write_1(sc->sc_iot, sc->sc_gpiobankh,BBC_GPIOBANK_INDEX, reg); 133 bus_space_read_1(sc->sc_iot, sc->sc_gpiobankh, BBC_GPIOBANK_INDEX); 134 135 136 sc->sc_blink.bl_func = ppm_led_blink; 137 sc->sc_blink.bl_arg = sc; 138 blink_led_register(&sc->sc_blink); 139 printf("\n"); 140 } 141 142 void 143 ppm_led_blink(void *vsc, int on) 144 { 145 struct ppm_softc *sc = vsc; 146 u_int8_t r; 147 148 r = bus_space_read_1(sc->sc_iot, sc->sc_gpioh, BBC_GPIO_PORT1_DATA); 149 if (on) 150 r |= GPIO_P2D_LED; 151 else 152 r &= ~GPIO_P2D_LED; 153 bus_space_write_1(sc->sc_iot, sc->sc_gpioh, BBC_GPIO_PORT1_DATA, r); 154 bus_space_read_1(sc->sc_iot, sc->sc_gpioh, BBC_GPIO_PORT1_DATA); 155 } 156