1*eb7eaf8dSmpi /* $OpenBSD: ppm.c,v 1.3 2021/10/24 17:05:04 mpi Exp $ */
2449bc0bdSjason
3449bc0bdSjason /*
4449bc0bdSjason * Copyright (c) 2006 Jason L. Wright (jason@thought.net)
5449bc0bdSjason * All rights reserved.
6449bc0bdSjason *
7449bc0bdSjason * Redistribution and use in source and binary forms, with or without
8449bc0bdSjason * modification, are permitted provided that the following conditions
9449bc0bdSjason * are met:
10449bc0bdSjason * 1. Redistributions of source code must retain the above copyright
11449bc0bdSjason * notice, this list of conditions and the following disclaimer.
12449bc0bdSjason * 2. Redistributions in binary form must reproduce the above copyright
13449bc0bdSjason * notice, this list of conditions and the following disclaimer in the
14449bc0bdSjason * documentation and/or other materials provided with the distribution.
15449bc0bdSjason *
16449bc0bdSjason * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17449bc0bdSjason * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18449bc0bdSjason * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19449bc0bdSjason * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20449bc0bdSjason * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21449bc0bdSjason * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22449bc0bdSjason * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23449bc0bdSjason * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24449bc0bdSjason * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25449bc0bdSjason * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26449bc0bdSjason * POSSIBILITY OF SUCH DAMAGE.
27449bc0bdSjason */
28449bc0bdSjason
29449bc0bdSjason #include <sys/param.h>
30449bc0bdSjason #include <sys/systm.h>
31449bc0bdSjason #include <sys/device.h>
32449bc0bdSjason
33449bc0bdSjason #include <machine/bus.h>
34449bc0bdSjason #include <machine/autoconf.h>
35449bc0bdSjason #include <machine/openfirm.h>
36449bc0bdSjason
37449bc0bdSjason #include <sparc64/dev/ebusreg.h>
38449bc0bdSjason #include <sparc64/dev/ebusvar.h>
39449bc0bdSjason
40449bc0bdSjason #define BBC_GPIOBANK_INDEX 0x0
41449bc0bdSjason #define BBC_GPIOBANK_DATA 0x1
42449bc0bdSjason
43449bc0bdSjason #define BBC_GPIO_PORT1_DATA 0x0
44449bc0bdSjason #define BBC_GPIO_PORT2_DATA 0x4
45449bc0bdSjason
46449bc0bdSjason #define GPIO_P2D_LED 0x2
47449bc0bdSjason
48449bc0bdSjason struct ppm_softc {
49449bc0bdSjason struct device sc_dv;
50449bc0bdSjason bus_space_tag_t sc_iot;
51449bc0bdSjason bus_space_handle_t sc_estarh;
52449bc0bdSjason bus_space_handle_t sc_rioh;
53449bc0bdSjason bus_space_handle_t sc_gpiobankh;
54449bc0bdSjason bus_space_handle_t sc_gpioh;
55449bc0bdSjason struct blink_led sc_blink;
56449bc0bdSjason };
57449bc0bdSjason
58449bc0bdSjason int ppm_match(struct device *, void *, void *);
59449bc0bdSjason void ppm_attach(struct device *, struct device *, void *);
60449bc0bdSjason
61*eb7eaf8dSmpi const struct cfattach ppm_ca = {
62449bc0bdSjason sizeof(struct ppm_softc), ppm_match, ppm_attach
63449bc0bdSjason };
64449bc0bdSjason
65449bc0bdSjason struct cfdriver ppm_cd = {
66449bc0bdSjason NULL, "ppm", DV_DULL
67449bc0bdSjason };
68449bc0bdSjason
69449bc0bdSjason void ppm_led_blink(void *, int);
70449bc0bdSjason
71449bc0bdSjason int
ppm_match(struct device * parent,void * match,void * aux)72449bc0bdSjason ppm_match(struct device *parent, void *match, void *aux)
73449bc0bdSjason {
74449bc0bdSjason struct ebus_attach_args *ea = aux;
75449bc0bdSjason
76449bc0bdSjason if (strcmp(ea->ea_name, "ppm"))
77449bc0bdSjason return (0);
78449bc0bdSjason return (1);
79449bc0bdSjason }
80449bc0bdSjason
81449bc0bdSjason void
ppm_attach(struct device * parent,struct device * self,void * aux)82449bc0bdSjason ppm_attach(struct device *parent, struct device *self, void *aux)
83449bc0bdSjason {
84449bc0bdSjason struct ppm_softc *sc = (void *)self;
85449bc0bdSjason struct ebus_attach_args *ea = aux;
86449bc0bdSjason u_int8_t reg;
87449bc0bdSjason
88449bc0bdSjason sc->sc_iot = ea->ea_memtag;
89449bc0bdSjason
90449bc0bdSjason if (ea->ea_nregs < 4) {
91449bc0bdSjason printf(": need %d regs\n", 4);
92449bc0bdSjason return;
93449bc0bdSjason }
94449bc0bdSjason
95449bc0bdSjason #if 0
96449bc0bdSjason if (ebus_bus_map(sc->sc_iot, 0,
97449bc0bdSjason EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size,
98449bc0bdSjason 0, 0, &sc->sc_estarh)) {
99449bc0bdSjason printf(": failed to map estar\n");
100449bc0bdSjason return;
101449bc0bdSjason }
102449bc0bdSjason #endif
103449bc0bdSjason #if 0
104449bc0bdSjason if (ebus_bus_map(sc->sc_iot, 0,
105449bc0bdSjason EBUS_PADDR_FROM_REG(&ea->ea_regs[1]), ea->ea_regs[1].size,
106449bc0bdSjason 0, 0, &sc->sc_rioh)) {
107449bc0bdSjason printf(": failed to map riohr\n");
108449bc0bdSjason return;
109449bc0bdSjason }
110449bc0bdSjason #endif
111449bc0bdSjason
112449bc0bdSjason if (ebus_bus_map(sc->sc_iot, 0,
113449bc0bdSjason EBUS_PADDR_FROM_REG(&ea->ea_regs[2]), ea->ea_regs[2].size,
114449bc0bdSjason 0, 0, &sc->sc_gpiobankh)) {
115449bc0bdSjason printf(": failed to map gpiobank\n");
116449bc0bdSjason return;
117449bc0bdSjason }
118449bc0bdSjason
119449bc0bdSjason if (ebus_bus_map(sc->sc_iot, 0,
120449bc0bdSjason EBUS_PADDR_FROM_REG(&ea->ea_regs[3]), ea->ea_regs[3].size,
121449bc0bdSjason 0, 0, &sc->sc_gpioh)) {
122449bc0bdSjason printf(": failed to map gpio\n");
123449bc0bdSjason return;
124449bc0bdSjason }
125449bc0bdSjason
126449bc0bdSjason bus_space_write_1(sc->sc_iot, sc->sc_gpiobankh,
127449bc0bdSjason BBC_GPIOBANK_INDEX, 0x22);
128449bc0bdSjason bus_space_read_1(sc->sc_iot, sc->sc_gpiobankh, BBC_GPIOBANK_INDEX);
129449bc0bdSjason reg = bus_space_read_1(sc->sc_iot, sc->sc_gpiobankh, BBC_GPIOBANK_DATA);
130449bc0bdSjason reg &= 0x7f;
131449bc0bdSjason bus_space_write_1(sc->sc_iot, sc->sc_gpiobankh,BBC_GPIOBANK_INDEX, reg);
132449bc0bdSjason bus_space_read_1(sc->sc_iot, sc->sc_gpiobankh, BBC_GPIOBANK_INDEX);
133449bc0bdSjason
134449bc0bdSjason
135449bc0bdSjason sc->sc_blink.bl_func = ppm_led_blink;
136449bc0bdSjason sc->sc_blink.bl_arg = sc;
137449bc0bdSjason blink_led_register(&sc->sc_blink);
138449bc0bdSjason printf("\n");
139449bc0bdSjason }
140449bc0bdSjason
141449bc0bdSjason void
ppm_led_blink(void * vsc,int on)142449bc0bdSjason ppm_led_blink(void *vsc, int on)
143449bc0bdSjason {
144449bc0bdSjason struct ppm_softc *sc = vsc;
145449bc0bdSjason u_int8_t r;
146449bc0bdSjason
147449bc0bdSjason r = bus_space_read_1(sc->sc_iot, sc->sc_gpioh, BBC_GPIO_PORT1_DATA);
148449bc0bdSjason if (on)
149449bc0bdSjason r |= GPIO_P2D_LED;
150449bc0bdSjason else
151449bc0bdSjason r &= ~GPIO_P2D_LED;
152449bc0bdSjason bus_space_write_1(sc->sc_iot, sc->sc_gpioh, BBC_GPIO_PORT1_DATA, r);
153449bc0bdSjason bus_space_read_1(sc->sc_iot, sc->sc_gpioh, BBC_GPIO_PORT1_DATA);
154449bc0bdSjason }
155