Annotation of sys/dev/i2c/pca9532.c, Revision 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