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