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