1e0efc557SJoerg Wunsch /*- 2e0efc557SJoerg Wunsch * Copyright (c) 1998 Nicolas Souchu, Marc Bouget 3e0efc557SJoerg Wunsch * Copyright (c) 2004 Joerg Wunsch 4e0efc557SJoerg Wunsch * All rights reserved. 5e0efc557SJoerg Wunsch * 6e0efc557SJoerg Wunsch * Redistribution and use in source and binary forms, with or without 7e0efc557SJoerg Wunsch * modification, are permitted provided that the following conditions 8e0efc557SJoerg Wunsch * are met: 9e0efc557SJoerg Wunsch * 1. Redistributions of source code must retain the above copyright 10e0efc557SJoerg Wunsch * notice, this list of conditions and the following disclaimer. 11e0efc557SJoerg Wunsch * 2. Redistributions in binary form must reproduce the above copyright 12e0efc557SJoerg Wunsch * notice, this list of conditions and the following disclaimer in the 13e0efc557SJoerg Wunsch * documentation and/or other materials provided with the distribution. 14e0efc557SJoerg Wunsch * 15e0efc557SJoerg Wunsch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16e0efc557SJoerg Wunsch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17e0efc557SJoerg Wunsch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18e0efc557SJoerg Wunsch * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19e0efc557SJoerg Wunsch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20e0efc557SJoerg Wunsch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21e0efc557SJoerg Wunsch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22e0efc557SJoerg Wunsch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23e0efc557SJoerg Wunsch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24e0efc557SJoerg Wunsch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25e0efc557SJoerg Wunsch * SUCH DAMAGE. 26e0efc557SJoerg Wunsch * 27e0efc557SJoerg Wunsch * $FreeBSD$ 28e0efc557SJoerg Wunsch */ 29e0efc557SJoerg Wunsch 3013e3657bSJohn Baldwin #ifndef __PCFVAR_H__ 3113e3657bSJohn Baldwin #define __PCFVAR_H__ 3213e3657bSJohn Baldwin 33e0efc557SJoerg Wunsch #define IO_PCFSIZE 2 34e0efc557SJoerg Wunsch 35e0efc557SJoerg Wunsch #define TIMEOUT 9999 /* XXX */ 36e0efc557SJoerg Wunsch 37e0efc557SJoerg Wunsch /* Status bits of S1 register (read only) */ 38e0efc557SJoerg Wunsch #define nBB 0x01 /* busy when low set/reset by STOP/START*/ 39e0efc557SJoerg Wunsch #define LAB 0x02 /* lost arbitration bit in multi-master mode */ 40e0efc557SJoerg Wunsch #define AAS 0x04 /* addressed as slave */ 41e0efc557SJoerg Wunsch #define LRB 0x08 /* last received byte when not AAS */ 42e0efc557SJoerg Wunsch #define AD0 0x08 /* general call received when AAS */ 43e0efc557SJoerg Wunsch #define BER 0x10 /* bus error, misplaced START or STOP */ 44e0efc557SJoerg Wunsch #define STS 0x20 /* STOP detected in slave receiver mode */ 45e0efc557SJoerg Wunsch #define PIN 0x80 /* pending interrupt not (r/w) */ 46e0efc557SJoerg Wunsch 47e0efc557SJoerg Wunsch /* Control bits of S1 register (write only) */ 48e0efc557SJoerg Wunsch #define ACK 0x01 49e0efc557SJoerg Wunsch #define STO 0x02 50e0efc557SJoerg Wunsch #define STA 0x04 51e0efc557SJoerg Wunsch #define ENI 0x08 52e0efc557SJoerg Wunsch #define ES2 0x10 53e0efc557SJoerg Wunsch #define ES1 0x20 54e0efc557SJoerg Wunsch #define ESO 0x40 55e0efc557SJoerg Wunsch 56e0efc557SJoerg Wunsch #define BUFSIZE 2048 57e0efc557SJoerg Wunsch 58e0efc557SJoerg Wunsch #define SLAVE_TRANSMITTER 0x1 59e0efc557SJoerg Wunsch #define SLAVE_RECEIVER 0x2 60e0efc557SJoerg Wunsch 61e0efc557SJoerg Wunsch #define PCF_DEFAULT_ADDR 0xaa 62e0efc557SJoerg Wunsch 63e0efc557SJoerg Wunsch struct pcf_softc { 64e0efc557SJoerg Wunsch u_char pcf_addr; /* interface I2C address */ 65e0efc557SJoerg Wunsch int pcf_flags; /* IIC_POLLED? */ 66e0efc557SJoerg Wunsch int pcf_slave_mode; /* receiver or transmitter */ 67e0efc557SJoerg Wunsch int pcf_started; /* 1 if start condition sent */ 68e0efc557SJoerg Wunsch 6913e3657bSJohn Baldwin struct mtx pcf_lock; 70e0efc557SJoerg Wunsch device_t iicbus; /* the corresponding iicbus */ 71e0efc557SJoerg Wunsch 72e0efc557SJoerg Wunsch /* Resource handling stuff. */ 73e0efc557SJoerg Wunsch struct resource *res_ioport; 74490a46bfSMarius Strobl int rid_ioport; 75e0efc557SJoerg Wunsch struct resource *res_irq; 76490a46bfSMarius Strobl int rid_irq; 77490a46bfSMarius Strobl void *intr_cookie; 78e0efc557SJoerg Wunsch }; 79e0efc557SJoerg Wunsch #define DEVTOSOFTC(dev) ((struct pcf_softc *)device_get_softc(dev)) 80e0efc557SJoerg Wunsch 8113e3657bSJohn Baldwin #define PCF_LOCK(sc) mtx_lock(&(sc)->pcf_lock) 8213e3657bSJohn Baldwin #define PCF_UNLOCK(sc) mtx_unlock(&(sc)->pcf_lock) 8313e3657bSJohn Baldwin #define PCF_ASSERT_LOCKED(sc) mtx_assert(&(sc)->pcf_lock, MA_OWNED) 8413e3657bSJohn Baldwin 85e0efc557SJoerg Wunsch /* 86e0efc557SJoerg Wunsch * PCF8584 datasheet : when operate at 8 MHz or more, a minimun time of 87e0efc557SJoerg Wunsch * 6 clocks cycles must be left between two consecutives access 88e0efc557SJoerg Wunsch */ 89e0efc557SJoerg Wunsch #define pcf_nops() DELAY(10) 90e0efc557SJoerg Wunsch 91e0efc557SJoerg Wunsch #define dummy_read(sc) pcf_get_S0(sc) 92e0efc557SJoerg Wunsch #define dummy_write(sc) pcf_set_S0(sc, 0) 93e0efc557SJoerg Wunsch 94e0efc557SJoerg Wunsch /* 95e0efc557SJoerg Wunsch * Specific register access to PCF8584 96e0efc557SJoerg Wunsch */ 975908d366SStefan Farfeleder static __inline void 98e0efc557SJoerg Wunsch pcf_set_S0(struct pcf_softc *sc, int data) 99e0efc557SJoerg Wunsch { 100490a46bfSMarius Strobl 10113e3657bSJohn Baldwin bus_write_1(sc->res_ioport, 0, data); 102e0efc557SJoerg Wunsch pcf_nops(); 103e0efc557SJoerg Wunsch } 104e0efc557SJoerg Wunsch 1055908d366SStefan Farfeleder static __inline void 106e0efc557SJoerg Wunsch pcf_set_S1(struct pcf_softc *sc, int data) 107e0efc557SJoerg Wunsch { 108490a46bfSMarius Strobl 10913e3657bSJohn Baldwin bus_write_1(sc->res_ioport, 1, data); 110e0efc557SJoerg Wunsch pcf_nops(); 111e0efc557SJoerg Wunsch } 112e0efc557SJoerg Wunsch 1135908d366SStefan Farfeleder static __inline char 114e0efc557SJoerg Wunsch pcf_get_S0(struct pcf_softc *sc) 115e0efc557SJoerg Wunsch { 116e0efc557SJoerg Wunsch char data; 117e0efc557SJoerg Wunsch 11813e3657bSJohn Baldwin data = bus_read_1(sc->res_ioport, 0); 119e0efc557SJoerg Wunsch pcf_nops(); 120e0efc557SJoerg Wunsch 121e0efc557SJoerg Wunsch return (data); 122e0efc557SJoerg Wunsch } 123e0efc557SJoerg Wunsch 1245908d366SStefan Farfeleder static __inline char 125e0efc557SJoerg Wunsch pcf_get_S1(struct pcf_softc *sc) 126e0efc557SJoerg Wunsch { 127e0efc557SJoerg Wunsch char data; 128e0efc557SJoerg Wunsch 12913e3657bSJohn Baldwin data = bus_read_1(sc->res_ioport, 1); 130e0efc557SJoerg Wunsch pcf_nops(); 131e0efc557SJoerg Wunsch 132e0efc557SJoerg Wunsch return (data); 133e0efc557SJoerg Wunsch } 134e0efc557SJoerg Wunsch 135e0efc557SJoerg Wunsch extern int pcf_repeated_start(device_t, u_char, int); 136e0efc557SJoerg Wunsch extern int pcf_start(device_t, u_char, int); 137e0efc557SJoerg Wunsch extern int pcf_stop(device_t); 138e0efc557SJoerg Wunsch extern int pcf_write(device_t, char *, int, int *, int); 139e0efc557SJoerg Wunsch extern int pcf_read(device_t, char *, int, int *, int, int); 140e0efc557SJoerg Wunsch extern int pcf_rst_card(device_t, u_char, u_char, u_char *); 141e0efc557SJoerg Wunsch extern driver_intr_t pcf_intr; 142e0efc557SJoerg Wunsch 143e0efc557SJoerg Wunsch #define PCF_MODVER 1 144e0efc557SJoerg Wunsch #define PCF_MINVER 1 145e0efc557SJoerg Wunsch #define PCF_MAXVER 1 146e0efc557SJoerg Wunsch #define PCF_PREFVER PCF_MODVER 14713e3657bSJohn Baldwin 14813e3657bSJohn Baldwin #endif /* !__PCFVAR_H__ */ 149