1 /* $OpenBSD: ppm.c,v 1.3 2021/10/24 17:05:04 mpi 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/param.h>
30 #include <sys/systm.h>
31 #include <sys/device.h>
32
33 #include <machine/bus.h>
34 #include <machine/autoconf.h>
35 #include <machine/openfirm.h>
36
37 #include <sparc64/dev/ebusreg.h>
38 #include <sparc64/dev/ebusvar.h>
39
40 #define BBC_GPIOBANK_INDEX 0x0
41 #define BBC_GPIOBANK_DATA 0x1
42
43 #define BBC_GPIO_PORT1_DATA 0x0
44 #define BBC_GPIO_PORT2_DATA 0x4
45
46 #define GPIO_P2D_LED 0x2
47
48 struct ppm_softc {
49 struct device sc_dv;
50 bus_space_tag_t sc_iot;
51 bus_space_handle_t sc_estarh;
52 bus_space_handle_t sc_rioh;
53 bus_space_handle_t sc_gpiobankh;
54 bus_space_handle_t sc_gpioh;
55 struct blink_led sc_blink;
56 };
57
58 int ppm_match(struct device *, void *, void *);
59 void ppm_attach(struct device *, struct device *, void *);
60
61 const struct cfattach ppm_ca = {
62 sizeof(struct ppm_softc), ppm_match, ppm_attach
63 };
64
65 struct cfdriver ppm_cd = {
66 NULL, "ppm", DV_DULL
67 };
68
69 void ppm_led_blink(void *, int);
70
71 int
ppm_match(struct device * parent,void * match,void * aux)72 ppm_match(struct device *parent, void *match, void *aux)
73 {
74 struct ebus_attach_args *ea = aux;
75
76 if (strcmp(ea->ea_name, "ppm"))
77 return (0);
78 return (1);
79 }
80
81 void
ppm_attach(struct device * parent,struct device * self,void * aux)82 ppm_attach(struct device *parent, struct device *self, void *aux)
83 {
84 struct ppm_softc *sc = (void *)self;
85 struct ebus_attach_args *ea = aux;
86 u_int8_t reg;
87
88 sc->sc_iot = ea->ea_memtag;
89
90 if (ea->ea_nregs < 4) {
91 printf(": need %d regs\n", 4);
92 return;
93 }
94
95 #if 0
96 if (ebus_bus_map(sc->sc_iot, 0,
97 EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size,
98 0, 0, &sc->sc_estarh)) {
99 printf(": failed to map estar\n");
100 return;
101 }
102 #endif
103 #if 0
104 if (ebus_bus_map(sc->sc_iot, 0,
105 EBUS_PADDR_FROM_REG(&ea->ea_regs[1]), ea->ea_regs[1].size,
106 0, 0, &sc->sc_rioh)) {
107 printf(": failed to map riohr\n");
108 return;
109 }
110 #endif
111
112 if (ebus_bus_map(sc->sc_iot, 0,
113 EBUS_PADDR_FROM_REG(&ea->ea_regs[2]), ea->ea_regs[2].size,
114 0, 0, &sc->sc_gpiobankh)) {
115 printf(": failed to map gpiobank\n");
116 return;
117 }
118
119 if (ebus_bus_map(sc->sc_iot, 0,
120 EBUS_PADDR_FROM_REG(&ea->ea_regs[3]), ea->ea_regs[3].size,
121 0, 0, &sc->sc_gpioh)) {
122 printf(": failed to map gpio\n");
123 return;
124 }
125
126 bus_space_write_1(sc->sc_iot, sc->sc_gpiobankh,
127 BBC_GPIOBANK_INDEX, 0x22);
128 bus_space_read_1(sc->sc_iot, sc->sc_gpiobankh, BBC_GPIOBANK_INDEX);
129 reg = bus_space_read_1(sc->sc_iot, sc->sc_gpiobankh, BBC_GPIOBANK_DATA);
130 reg &= 0x7f;
131 bus_space_write_1(sc->sc_iot, sc->sc_gpiobankh,BBC_GPIOBANK_INDEX, reg);
132 bus_space_read_1(sc->sc_iot, sc->sc_gpiobankh, BBC_GPIOBANK_INDEX);
133
134
135 sc->sc_blink.bl_func = ppm_led_blink;
136 sc->sc_blink.bl_arg = sc;
137 blink_led_register(&sc->sc_blink);
138 printf("\n");
139 }
140
141 void
ppm_led_blink(void * vsc,int on)142 ppm_led_blink(void *vsc, int on)
143 {
144 struct ppm_softc *sc = vsc;
145 u_int8_t r;
146
147 r = bus_space_read_1(sc->sc_iot, sc->sc_gpioh, BBC_GPIO_PORT1_DATA);
148 if (on)
149 r |= GPIO_P2D_LED;
150 else
151 r &= ~GPIO_P2D_LED;
152 bus_space_write_1(sc->sc_iot, sc->sc_gpioh, BBC_GPIO_PORT1_DATA, r);
153 bus_space_read_1(sc->sc_iot, sc->sc_gpioh, BBC_GPIO_PORT1_DATA);
154 }
155