Annotation of sys/dev/i2c/pca9532.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: pca9532.c,v 1.2 2006/06/17 23:00:47 drahn Exp $ */
2: /*
3: * Copyright (c) 2006 Dale Rahn <drahn@openbsd.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: #include <sys/param.h>
19: #include <sys/systm.h>
20: #include <sys/device.h>
21: #include <sys/kernel.h>
22: #include <sys/fcntl.h>
23: #include <sys/uio.h>
24: #include <sys/conf.h>
25: #include <sys/gpio.h>
26:
27:
28: #include <dev/i2c/i2cvar.h>
29: #include <dev/gpio/gpiovar.h>
30:
31: #include "gpio.h"
32:
33: /* driver for PCA 9532 */
34:
35: #define PCALED_ADDR 0x60
36:
37: #define PCALED_GPIO_NPINS 16
38:
39: struct pcaled_softc {
40: struct device sc_dev;
41: i2c_tag_t sc_tag;
42: int sc_addr;
43: struct gpio_chipset_tag sc_gpio_gc;
44: struct gpio_pin sc_gpio_pin[PCALED_GPIO_NPINS];
45:
46: };
47:
48: int pcaled_match(struct device *, void *, void *);
49: void pcaled_attach(struct device *, struct device *, void *);
50: int pcaled_gpio_pin_read(void *arg, int pin);
51: void pcaled_gpio_pin_write (void *arg, int pin, int value);
52: void pcaled_gpio_pin_ctl (void *arg, int pin, int flags);
53:
54: struct cfattach pcaled_ca = {
55: sizeof(struct pcaled_softc), pcaled_match, pcaled_attach
56: };
57:
58: struct cfdriver pcaled_cd = {
59: NULL, "pcaled", DV_DULL
60: };
61:
62: int
63: pcaled_match(struct device *parent, void *v, void *arg)
64: {
65: struct i2c_attach_args *ia = arg;
66: int ok = 0;
67: uint8_t cmd, data;
68:
69: if (ia->ia_addr != PCALED_ADDR)
70: return (0);
71: /* attempt to read input register 0 */
72: iic_acquire_bus(ia->ia_tag, I2C_F_POLL);
73: cmd = 0;
74: if (iic_exec(ia->ia_tag, I2C_OP_READ_WITH_STOP, ia->ia_addr,
75: &cmd, 1, &data, 1, I2C_F_POLL))
76: goto fail;
77: cmd = 9;
78: if (iic_exec(ia->ia_tag, I2C_OP_READ_WITH_STOP, ia->ia_addr,
79: &cmd, 1, &data, 1, I2C_F_POLL))
80: goto fail;
81: ok = 1;
82: fail:
83: iic_release_bus(ia->ia_tag, I2C_F_POLL);
84: return (ok);
85: }
86:
87: void
88: pcaled_attach(struct device *parent, struct device *self, void *arg)
89: {
90: struct pcaled_softc *sc = (void *)self;
91: struct i2c_attach_args *ia = arg;
92: struct gpiobus_attach_args gba;
93: int i;
94: uint8_t cmd, data;
95:
96: sc->sc_tag = ia->ia_tag;
97: sc->sc_addr = ia->ia_addr;
98:
99: iic_acquire_bus(sc->sc_tag, I2C_F_POLL);
100:
101: for (i = 0; i < PCALED_GPIO_NPINS; i++) {
102: sc->sc_gpio_pin[i].pin_num = i;
103: sc->sc_gpio_pin[i].pin_caps = GPIO_PIN_INOUT;
104: if (i < 8)
105: cmd = 0;
106: else
107: cmd = 1;
108: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
109: &cmd, 1, &data, 1, I2C_F_POLL))
110: goto fail; /* XXX */
111: sc->sc_gpio_pin[i].pin_state = (data >> (i & 3)) & 1;
112: }
113: sc->sc_gpio_gc.gp_cookie = sc;
114: sc->sc_gpio_gc.gp_pin_read = pcaled_gpio_pin_read;
115: sc->sc_gpio_gc.gp_pin_write = pcaled_gpio_pin_write;
116: sc->sc_gpio_gc.gp_pin_ctl = pcaled_gpio_pin_ctl;
117:
118: printf(": PCA9532 LED controller\n");
119:
120: gba.gba_name = "gpio";
121: gba.gba_gc = &sc->sc_gpio_gc;
122: gba.gba_pins = sc->sc_gpio_pin;
123: gba.gba_npins = PCALED_GPIO_NPINS;
124: #if NGPIO > 0
125: config_found(&sc->sc_dev, &gba, gpiobus_print);
126: #endif
127:
128: fail:
129: iic_release_bus(sc->sc_tag, I2C_F_POLL);
130: }
131:
132: int
133: pcaled_gpio_pin_read(void *arg, int pin)
134: {
135: struct pcaled_softc *sc = arg;
136: iic_acquire_bus(sc->sc_tag, I2C_F_POLL);
137: uint8_t cmd, data;
138:
139: if (pin < 8)
140: cmd = 0;
141: else
142: cmd = 1;
143: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
144: &cmd, 1, &data, 1, I2C_F_POLL))
145: goto fail; /* XXX */
146:
147: fail:
148: iic_release_bus(sc->sc_tag, I2C_F_POLL);
149: return (data >> (pin & 3)) & 1;
150: }
151:
152: void
153: pcaled_gpio_pin_write (void *arg, int pin, int value)
154: {
155: struct pcaled_softc *sc = arg;
156: uint8_t cmd, data;
157: if (pin < 4)
158: cmd = 6;
159: else if (pin < 8)
160: cmd = 7;
161: else if (pin < 12)
162: cmd = 8;
163: else
164: cmd = 9;
165: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
166: &cmd, 1, &data, 1, I2C_F_POLL))
167: goto fail; /* XXX */
168: data &= ~(0x3 << (2*(pin & 3)));
169: data |= (value << (2*(pin & 3)));
170:
171: if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr,
172: &cmd, 1, &data, 1, I2C_F_POLL))
173: goto fail; /* XXX */
174:
175: fail:
176: iic_release_bus(sc->sc_tag, I2C_F_POLL);
177: }
178:
179: void
180: pcaled_gpio_pin_ctl (void *arg, int pin, int flags)
181: {
182: /* XXX all pins are inout */
183: }
184:
CVSweb