1*1961a14aSEmmanuel Vadot /*- 2*1961a14aSEmmanuel Vadot * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG 3*1961a14aSEmmanuel Vadot * 4*1961a14aSEmmanuel Vadot * Redistribution and use in source and binary forms, with or without 5*1961a14aSEmmanuel Vadot * modification, are permitted provided that the following conditions 6*1961a14aSEmmanuel Vadot * are met: 7*1961a14aSEmmanuel Vadot * 1. Redistributions of source code must retain the above copyright 8*1961a14aSEmmanuel Vadot * notice, this list of conditions and the following disclaimer. 9*1961a14aSEmmanuel Vadot * 2. Redistributions in binary form must reproduce the above copyright 10*1961a14aSEmmanuel Vadot * notice, this list of conditions and the following disclaimer in the 11*1961a14aSEmmanuel Vadot * documentation and/or other materials provided with the distribution. 12*1961a14aSEmmanuel Vadot * 13*1961a14aSEmmanuel Vadot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14*1961a14aSEmmanuel Vadot * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15*1961a14aSEmmanuel Vadot * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16*1961a14aSEmmanuel Vadot * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17*1961a14aSEmmanuel Vadot * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18*1961a14aSEmmanuel Vadot * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19*1961a14aSEmmanuel Vadot * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20*1961a14aSEmmanuel Vadot * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21*1961a14aSEmmanuel Vadot * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22*1961a14aSEmmanuel Vadot * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23*1961a14aSEmmanuel Vadot * SUCH DAMAGE. 24*1961a14aSEmmanuel Vadot * 25*1961a14aSEmmanuel Vadot */ 26*1961a14aSEmmanuel Vadot 27*1961a14aSEmmanuel Vadot #ifndef _LINUX_I2C_H_ 28*1961a14aSEmmanuel Vadot #define _LINUX_I2C_H_ 29*1961a14aSEmmanuel Vadot 30*1961a14aSEmmanuel Vadot #include <sys/types.h> 31*1961a14aSEmmanuel Vadot #include <sys/errno.h> 32*1961a14aSEmmanuel Vadot #include <sys/systm.h> 33*1961a14aSEmmanuel Vadot 34*1961a14aSEmmanuel Vadot #include <linux/device.h> 35*1961a14aSEmmanuel Vadot 36*1961a14aSEmmanuel Vadot #define I2C_MAX_ADAPTER_NAME_LENGTH 32 37*1961a14aSEmmanuel Vadot 38*1961a14aSEmmanuel Vadot #define I2C_M_RD 0x0001 39*1961a14aSEmmanuel Vadot #define I2C_M_NOSTART 0x0002 40*1961a14aSEmmanuel Vadot #define I2C_M_STOP 0x0004 41*1961a14aSEmmanuel Vadot 42*1961a14aSEmmanuel Vadot /* No need for us */ 43*1961a14aSEmmanuel Vadot #define I2C_FUNC_I2C 0 44*1961a14aSEmmanuel Vadot #define I2C_FUNC_SMBUS_EMUL 0 45*1961a14aSEmmanuel Vadot #define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0 46*1961a14aSEmmanuel Vadot #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0 47*1961a14aSEmmanuel Vadot #define I2C_FUNC_10BIT_ADDR 0 48*1961a14aSEmmanuel Vadot 49*1961a14aSEmmanuel Vadot #define I2C_CLASS_DDC 0x8 50*1961a14aSEmmanuel Vadot #define I2C_CLASS_SPD 0x80 51*1961a14aSEmmanuel Vadot 52*1961a14aSEmmanuel Vadot struct i2c_adapter { 53*1961a14aSEmmanuel Vadot struct module *owner; 54*1961a14aSEmmanuel Vadot unsigned int class; 55*1961a14aSEmmanuel Vadot 56*1961a14aSEmmanuel Vadot char name[I2C_MAX_ADAPTER_NAME_LENGTH]; 57*1961a14aSEmmanuel Vadot struct device dev; 58*1961a14aSEmmanuel Vadot 59*1961a14aSEmmanuel Vadot const struct i2c_lock_operations *lock_ops; 60*1961a14aSEmmanuel Vadot const struct i2c_algorithm *algo; 61*1961a14aSEmmanuel Vadot void *algo_data; 62*1961a14aSEmmanuel Vadot 63*1961a14aSEmmanuel Vadot int retries; 64*1961a14aSEmmanuel Vadot void *data; 65*1961a14aSEmmanuel Vadot }; 66*1961a14aSEmmanuel Vadot 67*1961a14aSEmmanuel Vadot struct i2c_msg { 68*1961a14aSEmmanuel Vadot uint16_t addr; 69*1961a14aSEmmanuel Vadot uint16_t flags; 70*1961a14aSEmmanuel Vadot uint16_t len; 71*1961a14aSEmmanuel Vadot uint8_t *buf; 72*1961a14aSEmmanuel Vadot }; 73*1961a14aSEmmanuel Vadot 74*1961a14aSEmmanuel Vadot struct i2c_algorithm { 75*1961a14aSEmmanuel Vadot int (*master_xfer)(struct i2c_adapter *, struct i2c_msg *, int); 76*1961a14aSEmmanuel Vadot uint32_t (*functionality)(struct i2c_adapter *); 77*1961a14aSEmmanuel Vadot }; 78*1961a14aSEmmanuel Vadot 79*1961a14aSEmmanuel Vadot struct i2c_lock_operations { 80*1961a14aSEmmanuel Vadot void (*lock_bus)(struct i2c_adapter *, unsigned int); 81*1961a14aSEmmanuel Vadot int (*trylock_bus)(struct i2c_adapter *, unsigned int); 82*1961a14aSEmmanuel Vadot void (*unlock_bus)(struct i2c_adapter *, unsigned int); 83*1961a14aSEmmanuel Vadot }; 84*1961a14aSEmmanuel Vadot 85*1961a14aSEmmanuel Vadot int lkpi_i2c_add_adapter(struct i2c_adapter *adapter); 86*1961a14aSEmmanuel Vadot int lkpi_i2c_del_adapter(struct i2c_adapter *adapter); 87*1961a14aSEmmanuel Vadot 88*1961a14aSEmmanuel Vadot int lkpi_i2cbb_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs); 89*1961a14aSEmmanuel Vadot 90*1961a14aSEmmanuel Vadot #define i2c_add_adapter(adapter) lkpi_i2c_add_adapter(adapter) 91*1961a14aSEmmanuel Vadot #define i2c_del_adapter(adapter) lkpi_i2c_del_adapter(adapter) 92*1961a14aSEmmanuel Vadot 93*1961a14aSEmmanuel Vadot #define i2c_get_adapter(x) NULL 94*1961a14aSEmmanuel Vadot #define i2c_put_adapter(x) 95*1961a14aSEmmanuel Vadot 96*1961a14aSEmmanuel Vadot static inline int 97*1961a14aSEmmanuel Vadot do_i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs) 98*1961a14aSEmmanuel Vadot { 99*1961a14aSEmmanuel Vadot int ret, retries; 100*1961a14aSEmmanuel Vadot 101*1961a14aSEmmanuel Vadot retries = adapter->retries == 0 ? 1 : adapter->retries; 102*1961a14aSEmmanuel Vadot for (; retries != 0; retries--) { 103*1961a14aSEmmanuel Vadot if (adapter->algo->master_xfer != NULL) 104*1961a14aSEmmanuel Vadot ret = adapter->algo->master_xfer(adapter, msgs, nmsgs); 105*1961a14aSEmmanuel Vadot else 106*1961a14aSEmmanuel Vadot ret = lkpi_i2cbb_transfer(adapter, msgs, nmsgs); 107*1961a14aSEmmanuel Vadot if (ret != -EAGAIN) 108*1961a14aSEmmanuel Vadot break; 109*1961a14aSEmmanuel Vadot } 110*1961a14aSEmmanuel Vadot 111*1961a14aSEmmanuel Vadot return (ret); 112*1961a14aSEmmanuel Vadot } 113*1961a14aSEmmanuel Vadot 114*1961a14aSEmmanuel Vadot static inline int 115*1961a14aSEmmanuel Vadot i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs) 116*1961a14aSEmmanuel Vadot { 117*1961a14aSEmmanuel Vadot int ret; 118*1961a14aSEmmanuel Vadot 119*1961a14aSEmmanuel Vadot if (!adapter->algo) 120*1961a14aSEmmanuel Vadot return (-EOPNOTSUPP); 121*1961a14aSEmmanuel Vadot 122*1961a14aSEmmanuel Vadot if (adapter->lock_ops) 123*1961a14aSEmmanuel Vadot adapter->lock_ops->lock_bus(adapter, 0); 124*1961a14aSEmmanuel Vadot 125*1961a14aSEmmanuel Vadot ret = do_i2c_transfer(adapter, msgs, nmsgs); 126*1961a14aSEmmanuel Vadot 127*1961a14aSEmmanuel Vadot if (adapter->lock_ops) 128*1961a14aSEmmanuel Vadot adapter->lock_ops->unlock_bus(adapter, 0); 129*1961a14aSEmmanuel Vadot 130*1961a14aSEmmanuel Vadot return (ret); 131*1961a14aSEmmanuel Vadot } 132*1961a14aSEmmanuel Vadot 133*1961a14aSEmmanuel Vadot /* Unlocked version of i2c_transfer */ 134*1961a14aSEmmanuel Vadot static inline int 135*1961a14aSEmmanuel Vadot __i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs) 136*1961a14aSEmmanuel Vadot { 137*1961a14aSEmmanuel Vadot return (do_i2c_transfer(adapter, msgs, nmsgs)); 138*1961a14aSEmmanuel Vadot } 139*1961a14aSEmmanuel Vadot 140*1961a14aSEmmanuel Vadot static inline void 141*1961a14aSEmmanuel Vadot i2c_set_adapdata(struct i2c_adapter *adapter, void *data) 142*1961a14aSEmmanuel Vadot { 143*1961a14aSEmmanuel Vadot adapter->data = data; 144*1961a14aSEmmanuel Vadot } 145*1961a14aSEmmanuel Vadot 146*1961a14aSEmmanuel Vadot static inline void * 147*1961a14aSEmmanuel Vadot i2c_get_adapdata(struct i2c_adapter *adapter) 148*1961a14aSEmmanuel Vadot { 149*1961a14aSEmmanuel Vadot return (adapter->data); 150*1961a14aSEmmanuel Vadot } 151*1961a14aSEmmanuel Vadot 152*1961a14aSEmmanuel Vadot #endif /* _LINUX_I2C_H_ */ 153