1c3e2dc6bSNicolas Souchu /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3718cf2ccSPedro F. Giffuni * 4c17d4340SNicolas Souchu * Copyright (c) 1998, 2001 Nicolas Souchu 5c3e2dc6bSNicolas Souchu * All rights reserved. 6c3e2dc6bSNicolas Souchu * 7c3e2dc6bSNicolas Souchu * Redistribution and use in source and binary forms, with or without 8c3e2dc6bSNicolas Souchu * modification, are permitted provided that the following conditions 9c3e2dc6bSNicolas Souchu * are met: 10c3e2dc6bSNicolas Souchu * 1. Redistributions of source code must retain the above copyright 11c3e2dc6bSNicolas Souchu * notice, this list of conditions and the following disclaimer. 12c3e2dc6bSNicolas Souchu * 2. Redistributions in binary form must reproduce the above copyright 13c3e2dc6bSNicolas Souchu * notice, this list of conditions and the following disclaimer in the 14c3e2dc6bSNicolas Souchu * documentation and/or other materials provided with the distribution. 15c3e2dc6bSNicolas Souchu * 16c3e2dc6bSNicolas Souchu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17c3e2dc6bSNicolas Souchu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18c3e2dc6bSNicolas Souchu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19c3e2dc6bSNicolas Souchu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20c3e2dc6bSNicolas Souchu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21c3e2dc6bSNicolas Souchu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22c3e2dc6bSNicolas Souchu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23c3e2dc6bSNicolas Souchu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24c3e2dc6bSNicolas Souchu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25c3e2dc6bSNicolas Souchu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26c3e2dc6bSNicolas Souchu * SUCH DAMAGE. 27c3e2dc6bSNicolas Souchu */ 28c3e2dc6bSNicolas Souchu #ifndef __IICONF_H 29c3e2dc6bSNicolas Souchu #define __IICONF_H 30c3e2dc6bSNicolas Souchu 31c3e2dc6bSNicolas Souchu #include <sys/queue.h> 32efce3748SRui Paulo #include <dev/iicbus/iic.h> 33d7fac973SWarner Losh 34c3e2dc6bSNicolas Souchu 35d254af07SMatthew Dillon #define IICPRI (PZERO+8) /* XXX sleep/wakeup queue priority */ 36c3e2dc6bSNicolas Souchu 37c3e2dc6bSNicolas Souchu #define LSB 0x1 38c3e2dc6bSNicolas Souchu 39c3e2dc6bSNicolas Souchu /* 40ac8f374aSIan Lepore * Options affecting iicbus_request_bus() 41c3e2dc6bSNicolas Souchu */ 42c3e2dc6bSNicolas Souchu #define IIC_DONTWAIT 0 43c3e2dc6bSNicolas Souchu #define IIC_NOINTR 0 44c3e2dc6bSNicolas Souchu #define IIC_WAIT 0x1 45c3e2dc6bSNicolas Souchu #define IIC_INTR 0x2 46d0b70953SIan Lepore #define IIC_INTRWAIT (IIC_INTR | IIC_WAIT) 47ac8f374aSIan Lepore #define IIC_RECURSIVE 0x4 48422d05daSIan Lepore #define IIC_REQBUS_DEV 0x8 /* See struct iic_reqbus_data, below. */ 49422d05daSIan Lepore 50422d05daSIan Lepore /* 51422d05daSIan Lepore * The original iicbus->bridge callback api took a pointer to an int containing 52422d05daSIan Lepore * flags. The new api allows a pointer to this struct, with IIC_REQBUS_DEV set 53422d05daSIan Lepore * in the flags to let the implementation know the pointer is actually to this 54422d05daSIan Lepore * struct which has the flags word first, followed by the device_t of the 55422d05daSIan Lepore * requesting bus and device. 56422d05daSIan Lepore * 57422d05daSIan Lepore * Note that the requesting device may not be a i2c slave device which is a 58422d05daSIan Lepore * child of the requested bus -- it may be a mux device which is electrically 59422d05daSIan Lepore * part of the bus hierarchy, but whose driver belongs to some other bus 60422d05daSIan Lepore * hierarchy such as gpio. 61422d05daSIan Lepore */ 62422d05daSIan Lepore struct iic_reqbus_data { 63422d05daSIan Lepore int flags; /* Flags from the set defined above. */ 64422d05daSIan Lepore device_t bus; /* The iicbus being requested. */ 65422d05daSIan Lepore device_t dev; /* The device requesting the bus. */ 66422d05daSIan Lepore }; 67c3e2dc6bSNicolas Souchu 68c3e2dc6bSNicolas Souchu /* 69c3e2dc6bSNicolas Souchu * i2c modes 70c3e2dc6bSNicolas Souchu */ 71c3e2dc6bSNicolas Souchu #define IIC_MASTER 0x1 72c3e2dc6bSNicolas Souchu #define IIC_SLAVE 0x2 73c3e2dc6bSNicolas Souchu #define IIC_POLLED 0x4 74c3e2dc6bSNicolas Souchu 75c3e2dc6bSNicolas Souchu /* 76c3e2dc6bSNicolas Souchu * i2c speed 77c3e2dc6bSNicolas Souchu */ 78c3e2dc6bSNicolas Souchu #define IIC_UNKNOWN 0x0 79c3e2dc6bSNicolas Souchu #define IIC_SLOW 0x1 80c3e2dc6bSNicolas Souchu #define IIC_FAST 0x2 81c3e2dc6bSNicolas Souchu #define IIC_FASTEST 0x3 82c3e2dc6bSNicolas Souchu 8304f89a63SNicolas Souchu #define IIC_LAST_READ 0x1 8404f89a63SNicolas Souchu 8504f89a63SNicolas Souchu /* 8604f89a63SNicolas Souchu * callback index 8704f89a63SNicolas Souchu */ 8804f89a63SNicolas Souchu #define IIC_REQUEST_BUS 0x1 8904f89a63SNicolas Souchu #define IIC_RELEASE_BUS 0x2 9004f89a63SNicolas Souchu 91c3e2dc6bSNicolas Souchu /* 92c3e2dc6bSNicolas Souchu * interrupt events 93c3e2dc6bSNicolas Souchu */ 94c3e2dc6bSNicolas Souchu #define INTR_GENERAL 0x1 /* general call received */ 95c3e2dc6bSNicolas Souchu #define INTR_START 0x2 /* the I2C interface is addressed */ 96c3e2dc6bSNicolas Souchu #define INTR_STOP 0x3 /* stop condition received */ 97c3e2dc6bSNicolas Souchu #define INTR_RECEIVE 0x4 /* character received */ 98c3e2dc6bSNicolas Souchu #define INTR_TRANSMIT 0x5 /* character to transmit */ 99c3e2dc6bSNicolas Souchu #define INTR_ERROR 0x6 /* error */ 100c3e2dc6bSNicolas Souchu #define INTR_NOACK 0x7 /* no ack from master receiver */ 101c3e2dc6bSNicolas Souchu 102c3e2dc6bSNicolas Souchu /* 103c3e2dc6bSNicolas Souchu * adapter layer errors 104c3e2dc6bSNicolas Souchu */ 105453130d9SPedro F. Giffuni #define IIC_NOERR 0x0 /* no error occurred */ 106d1e99670SIan Lepore #define IIC_EBUSERR 0x1 /* bus error (hardware not in expected state) */ 107c3e2dc6bSNicolas Souchu #define IIC_ENOACK 0x2 /* ack not received until timeout */ 108c3e2dc6bSNicolas Souchu #define IIC_ETIMEOUT 0x3 /* timeout */ 109d1e99670SIan Lepore #define IIC_EBUSBSY 0x4 /* bus busy (reserved by another client) */ 110c3e2dc6bSNicolas Souchu #define IIC_ESTATUS 0x5 /* status error */ 111c3e2dc6bSNicolas Souchu #define IIC_EUNDERFLOW 0x6 /* slave ready for more data */ 112c3e2dc6bSNicolas Souchu #define IIC_EOVERFLOW 0x7 /* too much data */ 11304f89a63SNicolas Souchu #define IIC_ENOTSUPP 0x8 /* request not supported */ 11404f89a63SNicolas Souchu #define IIC_ENOADDR 0x9 /* no address assigned to the interface */ 115df38292aSIan Lepore #define IIC_ERESOURCE 0xa /* resources (memory, whatever) unavailable */ 116b897b02cSIan Lepore #define IIC_ERRNO __INT_MIN /* marker bit: errno is in low-order bits */ 117c3e2dc6bSNicolas Souchu 11848e5b426SIan Lepore /* 11948e5b426SIan Lepore * Note that all iicbus functions return IIC_Exxxxx status values, 12048e5b426SIan Lepore * except iic2errno() (obviously) and iicbus_started() (returns bool). 12148e5b426SIan Lepore */ 122df38292aSIan Lepore extern int iic2errno(int); 123b897b02cSIan Lepore extern int errno2iic(int); 124c3e2dc6bSNicolas Souchu extern int iicbus_request_bus(device_t, device_t, int); 125c3e2dc6bSNicolas Souchu extern int iicbus_release_bus(device_t, device_t); 126c3e2dc6bSNicolas Souchu extern device_t iicbus_alloc_bus(device_t); 127c3e2dc6bSNicolas Souchu 128c3e2dc6bSNicolas Souchu extern void iicbus_intr(device_t, int, char *); 129c3e2dc6bSNicolas Souchu 13004f89a63SNicolas Souchu extern int iicbus_null_repeated_start(device_t, u_char); 13104f89a63SNicolas Souchu extern int iicbus_null_callback(device_t, int, caddr_t); 13204f89a63SNicolas Souchu 13304f89a63SNicolas Souchu #define iicbus_reset(bus,speed,addr,oldaddr) \ 13404f89a63SNicolas Souchu (IICBUS_RESET(device_get_parent(bus), speed, addr, oldaddr)) 135c3e2dc6bSNicolas Souchu 136bf896bd0SNicolas Souchu /* basic I2C operations */ 137bf896bd0SNicolas Souchu extern int iicbus_started(device_t); 138bf896bd0SNicolas Souchu extern int iicbus_start(device_t, u_char, int); 139bf896bd0SNicolas Souchu extern int iicbus_stop(device_t); 140f8f3b24aSRoger Hardiman extern int iicbus_repeated_start(device_t, u_char, int); 14107defc61SWarner Losh extern int iicbus_write(device_t, const char *, int, int *, int); 142bf896bd0SNicolas Souchu extern int iicbus_read(device_t, char *, int, int *, int, int); 143bf896bd0SNicolas Souchu 144f8f3b24aSRoger Hardiman /* single byte read/write functions, start/stop not managed */ 145f8f3b24aSRoger Hardiman extern int iicbus_write_byte(device_t, char, int); 146f8f3b24aSRoger Hardiman extern int iicbus_read_byte(device_t, char *, int); 147f8f3b24aSRoger Hardiman 148bf896bd0SNicolas Souchu /* Read/write operations with start/stop conditions managed */ 149c3e2dc6bSNicolas Souchu extern int iicbus_block_write(device_t, u_char, char *, int, int *); 150c3e2dc6bSNicolas Souchu extern int iicbus_block_read(device_t, u_char, char *, int, int *); 151c3e2dc6bSNicolas Souchu 152d7fac973SWarner Losh /* vectors of iic operations to pass to bridge */ 153d7fac973SWarner Losh int iicbus_transfer(device_t bus, struct iic_msg *msgs, uint32_t nmsgs); 1544c1e5d32SIan Lepore int iicbus_transfer_excl(device_t bus, struct iic_msg *msgs, uint32_t nmsgs, 1554c1e5d32SIan Lepore int how); 156d7fac973SWarner Losh int iicbus_transfer_gen(device_t bus, struct iic_msg *msgs, uint32_t nmsgs); 157d7fac973SWarner Losh 1587ec74c58SIan Lepore /* 1597ec74c58SIan Lepore * Simple register read/write routines, but the "register" can be any size. 1607ec74c58SIan Lepore * The transfers are done with iicbus_transfer_excl(). Reads use a repeat-start 1617ec74c58SIan Lepore * between sending the address and reading; writes use a single start/stop. 1627ec74c58SIan Lepore */ 1637ec74c58SIan Lepore int iicdev_readfrom(device_t _slavedev, uint8_t _regaddr, void *_buffer, 1647ec74c58SIan Lepore uint16_t _buflen, int _waithow); 1657ec74c58SIan Lepore int iicdev_writeto(device_t _slavedev, uint8_t _regaddr, void *_buffer, 1667ec74c58SIan Lepore uint16_t _buflen, int _waithow); 1677ec74c58SIan Lepore 168c17d4340SNicolas Souchu #define IICBUS_MODVER 1 169c17d4340SNicolas Souchu #define IICBUS_MINVER 1 170c17d4340SNicolas Souchu #define IICBUS_MAXVER 1 171c17d4340SNicolas Souchu #define IICBUS_PREFVER IICBUS_MODVER 172c17d4340SNicolas Souchu 1739c77e81bSJohn-Mark Gurney extern driver_t iicbb_driver; 1749c77e81bSJohn-Mark Gurney 175c17d4340SNicolas Souchu #define IICBB_MODVER 1 176c17d4340SNicolas Souchu #define IICBB_MINVER 1 177c17d4340SNicolas Souchu #define IICBB_MAXVER 1 178c17d4340SNicolas Souchu #define IICBB_PREFVER IICBB_MODVER 179c17d4340SNicolas Souchu 180c3e2dc6bSNicolas Souchu #endif 181