Annotation of sys/dev/gpio/gpioow.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: gpioow.c,v 1.2 2006/06/23 06:27:11 miod Exp $ */
2:
3: /*
4: * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org>
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: /*
20: * 1-Wire bus bit-banging through GPIO pin.
21: */
22:
23: #include <sys/param.h>
24: #include <sys/systm.h>
25: #include <sys/device.h>
26: #include <sys/gpio.h>
27:
28: #include <dev/gpio/gpiovar.h>
29:
30: #include <dev/onewire/onewirevar.h>
31:
32: #define GPIOOW_NPINS 1
33: #define GPIOOW_PIN_DATA 0
34:
35: struct gpioow_softc {
36: struct device sc_dev;
37:
38: void * sc_gpio;
39: struct gpio_pinmap sc_map;
40: int __map[GPIOOW_NPINS];
41:
42: struct onewire_bus sc_ow_bus;
43: struct device * sc_ow_dev;
44:
45: int sc_data;
46: int sc_dying;
47: };
48:
49: int gpioow_match(struct device *, void *, void *);
50: void gpioow_attach(struct device *, struct device *, void *);
51: int gpioow_detach(struct device *, int);
52: int gpioow_activate(struct device *, enum devact);
53:
54: int gpioow_ow_reset(void *);
55: int gpioow_ow_bit(void *, int);
56:
57: void gpioow_bb_rx(void *);
58: void gpioow_bb_tx(void *);
59: int gpioow_bb_get(void *);
60: void gpioow_bb_set(void *, int);
61:
62: struct cfattach gpioow_ca = {
63: sizeof(struct gpioow_softc),
64: gpioow_match,
65: gpioow_attach,
66: gpioow_detach,
67: gpioow_activate
68: };
69:
70: struct cfdriver gpioow_cd = {
71: NULL, "gpioow", DV_DULL
72: };
73:
74: static const struct onewire_bbops gpioow_bbops = {
75: gpioow_bb_rx,
76: gpioow_bb_tx,
77: gpioow_bb_get,
78: gpioow_bb_set
79: };
80:
81: int
82: gpioow_match(struct device *parent, void *match, void *aux)
83: {
84: struct cfdata *cf = match;
85:
86: return (strcmp(cf->cf_driver->cd_name, "gpioow") == 0);
87: }
88:
89: void
90: gpioow_attach(struct device *parent, struct device *self, void *aux)
91: {
92: struct gpioow_softc *sc = (struct gpioow_softc *)self;
93: struct gpio_attach_args *ga = aux;
94: struct onewirebus_attach_args oba;
95: int caps;
96:
97: /* Check that we have enough pins */
98: if (gpio_npins(ga->ga_mask) != GPIOOW_NPINS) {
99: printf(": invalid pin mask\n");
100: return;
101: }
102:
103: /* Map pins */
104: sc->sc_gpio = ga->ga_gpio;
105: sc->sc_map.pm_map = sc->__map;
106: if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask,
107: &sc->sc_map)) {
108: printf(": can't map pins\n");
109: return;
110: }
111:
112: /* Configure data pin */
113: caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA);
114: if (!(caps & GPIO_PIN_OUTPUT)) {
115: printf(": data pin is unable to drive output\n");
116: goto fail;
117: }
118: if (!(caps & GPIO_PIN_INPUT)) {
119: printf(": data pin is unable to read input\n");
120: goto fail;
121: }
122: printf(": DATA[%d]", sc->sc_map.pm_map[GPIOOW_PIN_DATA]);
123: sc->sc_data = GPIO_PIN_OUTPUT;
124: if (caps & GPIO_PIN_OPENDRAIN) {
125: printf(" open-drain");
126: sc->sc_data |= GPIO_PIN_OPENDRAIN;
127: } else if ((caps & GPIO_PIN_PUSHPULL) && (caps & GPIO_PIN_TRISTATE)) {
128: printf(" push-pull tri-state");
129: sc->sc_data |= GPIO_PIN_PUSHPULL;
130: }
131: if (caps & GPIO_PIN_PULLUP) {
132: printf(" pull-up");
133: sc->sc_data |= GPIO_PIN_PULLUP;
134: }
135: gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA, sc->sc_data);
136:
137: printf("\n");
138:
139: /* Attach 1-Wire bus */
140: sc->sc_ow_bus.bus_cookie = sc;
141: sc->sc_ow_bus.bus_reset = gpioow_ow_reset;
142: sc->sc_ow_bus.bus_bit = gpioow_ow_bit;
143:
144: bzero(&oba, sizeof(oba));
145: oba.oba_bus = &sc->sc_ow_bus;
146: sc->sc_ow_dev = config_found(self, &oba, onewirebus_print);
147:
148: return;
149:
150: fail:
151: gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
152: }
153:
154: int
155: gpioow_detach(struct device *self, int flags)
156: {
157: struct gpioow_softc *sc = (struct gpioow_softc *)self;
158: int rv = 0;
159:
160: if (sc->sc_ow_dev != NULL)
161: rv = config_detach(sc->sc_ow_dev, flags);
162:
163: return (rv);
164: }
165:
166: int
167: gpioow_activate(struct device *self, enum devact act)
168: {
169: struct gpioow_softc *sc = (struct gpioow_softc *)self;
170: int rv = 0;
171:
172: switch (act) {
173: case DVACT_ACTIVATE:
174: break;
175: case DVACT_DEACTIVATE:
176: sc->sc_dying = 1;
177: if (sc->sc_ow_dev != NULL)
178: rv = config_deactivate(sc->sc_ow_dev);
179: break;
180: }
181:
182: return (rv);
183: }
184:
185: int
186: gpioow_ow_reset(void *arg)
187: {
188: return (onewire_bb_reset(&gpioow_bbops, arg));
189: }
190:
191: int
192: gpioow_ow_bit(void *arg, int value)
193: {
194: return (onewire_bb_bit(&gpioow_bbops, arg, value));
195: }
196:
197: void
198: gpioow_bb_rx(void *arg)
199: {
200: struct gpioow_softc *sc = arg;
201: int data = sc->sc_data;
202:
203: data &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
204: data |= GPIO_PIN_INPUT;
205: if (data & GPIO_PIN_PUSHPULL)
206: data |= GPIO_PIN_TRISTATE;
207: if (sc->sc_data != data) {
208: sc->sc_data = data;
209: gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA,
210: sc->sc_data);
211: }
212: }
213:
214: void
215: gpioow_bb_tx(void *arg)
216: {
217: struct gpioow_softc *sc = arg;
218: int data = sc->sc_data;
219:
220: data &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
221: data |= GPIO_PIN_OUTPUT;
222: if (sc->sc_data != data) {
223: sc->sc_data = data;
224: gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA,
225: sc->sc_data);
226: }
227: }
228:
229: int
230: gpioow_bb_get(void *arg)
231: {
232: struct gpioow_softc *sc = arg;
233:
234: return (gpio_pin_read(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA) ==
235: GPIO_PIN_HIGH ? 1 : 0);
236: }
237:
238: void
239: gpioow_bb_set(void *arg, int value)
240: {
241: struct gpioow_softc *sc = arg;
242:
243: gpio_pin_write(sc->sc_gpio, &sc->sc_map, GPIOOW_PIN_DATA,
244: value ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
245: }
CVSweb