11961a14aSEmmanuel Vadot /*- 21961a14aSEmmanuel Vadot * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG 31961a14aSEmmanuel Vadot * 41961a14aSEmmanuel Vadot * Redistribution and use in source and binary forms, with or without 51961a14aSEmmanuel Vadot * modification, are permitted provided that the following conditions 61961a14aSEmmanuel Vadot * are met: 71961a14aSEmmanuel Vadot * 1. Redistributions of source code must retain the above copyright 81961a14aSEmmanuel Vadot * notice, this list of conditions and the following disclaimer. 91961a14aSEmmanuel Vadot * 2. Redistributions in binary form must reproduce the above copyright 101961a14aSEmmanuel Vadot * notice, this list of conditions and the following disclaimer in the 111961a14aSEmmanuel Vadot * documentation and/or other materials provided with the distribution. 121961a14aSEmmanuel Vadot * 131961a14aSEmmanuel Vadot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 141961a14aSEmmanuel Vadot * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 151961a14aSEmmanuel Vadot * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 161961a14aSEmmanuel Vadot * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 171961a14aSEmmanuel Vadot * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 181961a14aSEmmanuel Vadot * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 191961a14aSEmmanuel Vadot * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 201961a14aSEmmanuel Vadot * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 211961a14aSEmmanuel Vadot * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 221961a14aSEmmanuel Vadot * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 231961a14aSEmmanuel Vadot * SUCH DAMAGE. 241961a14aSEmmanuel Vadot * 251961a14aSEmmanuel Vadot */ 261961a14aSEmmanuel Vadot 271961a14aSEmmanuel Vadot #ifndef _LINUX_I2C_H_ 281961a14aSEmmanuel Vadot #define _LINUX_I2C_H_ 291961a14aSEmmanuel Vadot 301961a14aSEmmanuel Vadot #include <sys/types.h> 311961a14aSEmmanuel Vadot #include <sys/errno.h> 321961a14aSEmmanuel Vadot #include <sys/systm.h> 331961a14aSEmmanuel Vadot 341961a14aSEmmanuel Vadot #include <linux/device.h> 351961a14aSEmmanuel Vadot 361961a14aSEmmanuel Vadot #define I2C_MAX_ADAPTER_NAME_LENGTH 32 371961a14aSEmmanuel Vadot 381961a14aSEmmanuel Vadot #define I2C_M_RD 0x0001 391961a14aSEmmanuel Vadot #define I2C_M_NOSTART 0x0002 401961a14aSEmmanuel Vadot #define I2C_M_STOP 0x0004 411961a14aSEmmanuel Vadot 421961a14aSEmmanuel Vadot /* No need for us */ 431961a14aSEmmanuel Vadot #define I2C_FUNC_I2C 0 441961a14aSEmmanuel Vadot #define I2C_FUNC_SMBUS_EMUL 0 451961a14aSEmmanuel Vadot #define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0 461961a14aSEmmanuel Vadot #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0 471961a14aSEmmanuel Vadot #define I2C_FUNC_10BIT_ADDR 0 481961a14aSEmmanuel Vadot 491961a14aSEmmanuel Vadot #define I2C_CLASS_DDC 0x8 501961a14aSEmmanuel Vadot #define I2C_CLASS_SPD 0x80 511961a14aSEmmanuel Vadot 521961a14aSEmmanuel Vadot struct i2c_adapter { 531961a14aSEmmanuel Vadot struct module *owner; 541961a14aSEmmanuel Vadot unsigned int class; 551961a14aSEmmanuel Vadot 561961a14aSEmmanuel Vadot char name[I2C_MAX_ADAPTER_NAME_LENGTH]; 571961a14aSEmmanuel Vadot struct device dev; 581961a14aSEmmanuel Vadot 591961a14aSEmmanuel Vadot const struct i2c_lock_operations *lock_ops; 601961a14aSEmmanuel Vadot const struct i2c_algorithm *algo; 611961a14aSEmmanuel Vadot void *algo_data; 621961a14aSEmmanuel Vadot 631961a14aSEmmanuel Vadot int retries; 641961a14aSEmmanuel Vadot void *data; 651961a14aSEmmanuel Vadot }; 661961a14aSEmmanuel Vadot 671961a14aSEmmanuel Vadot struct i2c_msg { 681961a14aSEmmanuel Vadot uint16_t addr; 691961a14aSEmmanuel Vadot uint16_t flags; 701961a14aSEmmanuel Vadot uint16_t len; 711961a14aSEmmanuel Vadot uint8_t *buf; 721961a14aSEmmanuel Vadot }; 731961a14aSEmmanuel Vadot 741961a14aSEmmanuel Vadot struct i2c_algorithm { 751961a14aSEmmanuel Vadot int (*master_xfer)(struct i2c_adapter *, struct i2c_msg *, int); 761961a14aSEmmanuel Vadot uint32_t (*functionality)(struct i2c_adapter *); 771961a14aSEmmanuel Vadot }; 781961a14aSEmmanuel Vadot 791961a14aSEmmanuel Vadot struct i2c_lock_operations { 801961a14aSEmmanuel Vadot void (*lock_bus)(struct i2c_adapter *, unsigned int); 811961a14aSEmmanuel Vadot int (*trylock_bus)(struct i2c_adapter *, unsigned int); 821961a14aSEmmanuel Vadot void (*unlock_bus)(struct i2c_adapter *, unsigned int); 831961a14aSEmmanuel Vadot }; 841961a14aSEmmanuel Vadot 851961a14aSEmmanuel Vadot int lkpi_i2c_add_adapter(struct i2c_adapter *adapter); 861961a14aSEmmanuel Vadot int lkpi_i2c_del_adapter(struct i2c_adapter *adapter); 871961a14aSEmmanuel Vadot 881961a14aSEmmanuel Vadot int lkpi_i2cbb_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs); 891961a14aSEmmanuel Vadot 901961a14aSEmmanuel Vadot #define i2c_add_adapter(adapter) lkpi_i2c_add_adapter(adapter) 911961a14aSEmmanuel Vadot #define i2c_del_adapter(adapter) lkpi_i2c_del_adapter(adapter) 921961a14aSEmmanuel Vadot 931961a14aSEmmanuel Vadot #define i2c_get_adapter(x) NULL 941961a14aSEmmanuel Vadot #define i2c_put_adapter(x) 951961a14aSEmmanuel Vadot 961961a14aSEmmanuel Vadot static inline int 971961a14aSEmmanuel Vadot do_i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs) 981961a14aSEmmanuel Vadot { 991961a14aSEmmanuel Vadot int ret, retries; 1001961a14aSEmmanuel Vadot 1011961a14aSEmmanuel Vadot retries = adapter->retries == 0 ? 1 : adapter->retries; 1021961a14aSEmmanuel Vadot for (; retries != 0; retries--) { 103*63641805SEmmanuel Vadot if (adapter->algo != NULL && adapter->algo->master_xfer != NULL) 1041961a14aSEmmanuel Vadot ret = adapter->algo->master_xfer(adapter, msgs, nmsgs); 1051961a14aSEmmanuel Vadot else 1061961a14aSEmmanuel Vadot ret = lkpi_i2cbb_transfer(adapter, msgs, nmsgs); 1071961a14aSEmmanuel Vadot if (ret != -EAGAIN) 1081961a14aSEmmanuel Vadot break; 1091961a14aSEmmanuel Vadot } 1101961a14aSEmmanuel Vadot 1111961a14aSEmmanuel Vadot return (ret); 1121961a14aSEmmanuel Vadot } 1131961a14aSEmmanuel Vadot 1141961a14aSEmmanuel Vadot static inline int 1151961a14aSEmmanuel Vadot i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs) 1161961a14aSEmmanuel Vadot { 1171961a14aSEmmanuel Vadot int ret; 1181961a14aSEmmanuel Vadot 119*63641805SEmmanuel Vadot if (adapter->algo == NULL && adapter->algo_data == NULL) 1201961a14aSEmmanuel Vadot return (-EOPNOTSUPP); 1211961a14aSEmmanuel Vadot 1221961a14aSEmmanuel Vadot if (adapter->lock_ops) 1231961a14aSEmmanuel Vadot adapter->lock_ops->lock_bus(adapter, 0); 1241961a14aSEmmanuel Vadot 1251961a14aSEmmanuel Vadot ret = do_i2c_transfer(adapter, msgs, nmsgs); 1261961a14aSEmmanuel Vadot 1271961a14aSEmmanuel Vadot if (adapter->lock_ops) 1281961a14aSEmmanuel Vadot adapter->lock_ops->unlock_bus(adapter, 0); 1291961a14aSEmmanuel Vadot 1301961a14aSEmmanuel Vadot return (ret); 1311961a14aSEmmanuel Vadot } 1321961a14aSEmmanuel Vadot 1331961a14aSEmmanuel Vadot /* Unlocked version of i2c_transfer */ 1341961a14aSEmmanuel Vadot static inline int 1351961a14aSEmmanuel Vadot __i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs) 1361961a14aSEmmanuel Vadot { 1371961a14aSEmmanuel Vadot return (do_i2c_transfer(adapter, msgs, nmsgs)); 1381961a14aSEmmanuel Vadot } 1391961a14aSEmmanuel Vadot 1401961a14aSEmmanuel Vadot static inline void 1411961a14aSEmmanuel Vadot i2c_set_adapdata(struct i2c_adapter *adapter, void *data) 1421961a14aSEmmanuel Vadot { 1431961a14aSEmmanuel Vadot adapter->data = data; 1441961a14aSEmmanuel Vadot } 1451961a14aSEmmanuel Vadot 1461961a14aSEmmanuel Vadot static inline void * 1471961a14aSEmmanuel Vadot i2c_get_adapdata(struct i2c_adapter *adapter) 1481961a14aSEmmanuel Vadot { 1491961a14aSEmmanuel Vadot return (adapter->data); 1501961a14aSEmmanuel Vadot } 1511961a14aSEmmanuel Vadot 1521961a14aSEmmanuel Vadot #endif /* _LINUX_I2C_H_ */ 153