1b5b5b320SKhalil Blaiech // SPDX-License-Identifier: GPL-2.0 2b5b5b320SKhalil Blaiech /* 3b5b5b320SKhalil Blaiech * Mellanox BlueField I2C bus driver 4b5b5b320SKhalil Blaiech * 5b5b5b320SKhalil Blaiech * Copyright (C) 2020 Mellanox Technologies, Ltd. 6b5b5b320SKhalil Blaiech */ 7b5b5b320SKhalil Blaiech 8b5b5b320SKhalil Blaiech #include <linux/acpi.h> 9b5b5b320SKhalil Blaiech #include <linux/delay.h> 10b5b5b320SKhalil Blaiech #include <linux/err.h> 11b5b5b320SKhalil Blaiech #include <linux/interrupt.h> 12b5b5b320SKhalil Blaiech #include <linux/i2c.h> 13b5b5b320SKhalil Blaiech #include <linux/io.h> 14b5b5b320SKhalil Blaiech #include <linux/kernel.h> 15b5b5b320SKhalil Blaiech #include <linux/module.h> 16b5b5b320SKhalil Blaiech #include <linux/mutex.h> 17b5b5b320SKhalil Blaiech #include <linux/of_device.h> 18b5b5b320SKhalil Blaiech #include <linux/platform_device.h> 19b5b5b320SKhalil Blaiech #include <linux/string.h> 20b5b5b320SKhalil Blaiech 21b5b5b320SKhalil Blaiech /* Defines what functionality is present. */ 22b5b5b320SKhalil Blaiech #define MLXBF_I2C_FUNC_SMBUS_BLOCK \ 23b5b5b320SKhalil Blaiech (I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL) 24b5b5b320SKhalil Blaiech 25b5b5b320SKhalil Blaiech #define MLXBF_I2C_FUNC_SMBUS_DEFAULT \ 26b5b5b320SKhalil Blaiech (I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | \ 27b5b5b320SKhalil Blaiech I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK | \ 28b5b5b320SKhalil Blaiech I2C_FUNC_SMBUS_PROC_CALL) 29b5b5b320SKhalil Blaiech 30b5b5b320SKhalil Blaiech #define MLXBF_I2C_FUNC_ALL \ 31b5b5b320SKhalil Blaiech (MLXBF_I2C_FUNC_SMBUS_DEFAULT | MLXBF_I2C_FUNC_SMBUS_BLOCK | \ 32b5b5b320SKhalil Blaiech I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SLAVE) 33b5b5b320SKhalil Blaiech 34b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_MAX 3 35b5b5b320SKhalil Blaiech 36b5b5b320SKhalil Blaiech /* Shared resources info in BlueField platforms. */ 37b5b5b320SKhalil Blaiech 38b5b5b320SKhalil Blaiech #define MLXBF_I2C_COALESCE_TYU_ADDR 0x02801300 39b5b5b320SKhalil Blaiech #define MLXBF_I2C_COALESCE_TYU_SIZE 0x010 40b5b5b320SKhalil Blaiech 41b5b5b320SKhalil Blaiech #define MLXBF_I2C_GPIO_TYU_ADDR 0x02802000 42b5b5b320SKhalil Blaiech #define MLXBF_I2C_GPIO_TYU_SIZE 0x100 43b5b5b320SKhalil Blaiech 44b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_TYU_ADDR 0x02800358 45b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_TYU_SIZE 0x008 46b5b5b320SKhalil Blaiech 47b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_YU_ADDR 0x02800c30 48b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_YU_SIZE 0x00c 49b5b5b320SKhalil Blaiech 50b5b5b320SKhalil Blaiech #define MLXBF_I2C_SHARED_RES_MAX 3 51b5b5b320SKhalil Blaiech 52b5b5b320SKhalil Blaiech /* 53b5b5b320SKhalil Blaiech * Note that the following SMBus, CAUSE, GPIO and PLL register addresses 54b5b5b320SKhalil Blaiech * refer to their respective offsets relative to the corresponding 55b5b5b320SKhalil Blaiech * memory-mapped region whose addresses are specified in either the DT or 56b5b5b320SKhalil Blaiech * the ACPI tables or above. 57b5b5b320SKhalil Blaiech */ 58b5b5b320SKhalil Blaiech 59b5b5b320SKhalil Blaiech /* 60b5b5b320SKhalil Blaiech * SMBus Master core clock frequency. Timing configurations are 61b5b5b320SKhalil Blaiech * strongly dependent on the core clock frequency of the SMBus 62b5b5b320SKhalil Blaiech * Master. Default value is set to 400MHz. 63b5b5b320SKhalil Blaiech */ 64b5b5b320SKhalil Blaiech #define MLXBF_I2C_TYU_PLL_OUT_FREQ (400 * 1000 * 1000) 6567ee9fdaSKhalil Blaiech /* Reference clock for Bluefield - 156 MHz. */ 6667ee9fdaSKhalil Blaiech #define MLXBF_I2C_PLL_IN_FREQ (156 * 1000 * 1000) 67b5b5b320SKhalil Blaiech 68b5b5b320SKhalil Blaiech /* Constant used to determine the PLL frequency. */ 69b5b5b320SKhalil Blaiech #define MLNXBF_I2C_COREPLL_CONST 16384 70b5b5b320SKhalil Blaiech 71b5b5b320SKhalil Blaiech /* PLL registers. */ 72b5b5b320SKhalil Blaiech #define MLXBF_I2C_CORE_PLL_REG0 0x0 73b5b5b320SKhalil Blaiech #define MLXBF_I2C_CORE_PLL_REG1 0x4 74b5b5b320SKhalil Blaiech #define MLXBF_I2C_CORE_PLL_REG2 0x8 75b5b5b320SKhalil Blaiech 76b5b5b320SKhalil Blaiech /* OR cause register. */ 77b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_OR_EVTEN0 0x14 78b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_OR_CLEAR 0x18 79b5b5b320SKhalil Blaiech 80b5b5b320SKhalil Blaiech /* Arbiter Cause Register. */ 81b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_ARBITER 0x1c 82b5b5b320SKhalil Blaiech 83b5b5b320SKhalil Blaiech /* 84b5b5b320SKhalil Blaiech * Cause Status flags. Note that those bits might be considered 85b5b5b320SKhalil Blaiech * as interrupt enabled bits. 86b5b5b320SKhalil Blaiech */ 87b5b5b320SKhalil Blaiech 88b5b5b320SKhalil Blaiech /* Transaction ended with STOP. */ 89b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_TRANSACTION_ENDED BIT(0) 90b5b5b320SKhalil Blaiech /* Master arbitration lost. */ 91b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_M_ARBITRATION_LOST BIT(1) 92b5b5b320SKhalil Blaiech /* Unexpected start detected. */ 93b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_UNEXPECTED_START BIT(2) 94b5b5b320SKhalil Blaiech /* Unexpected stop detected. */ 95b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_UNEXPECTED_STOP BIT(3) 96b5b5b320SKhalil Blaiech /* Wait for transfer continuation. */ 97b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_WAIT_FOR_FW_DATA BIT(4) 98b5b5b320SKhalil Blaiech /* Failed to generate STOP. */ 99b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_PUT_STOP_FAILED BIT(5) 100b5b5b320SKhalil Blaiech /* Failed to generate START. */ 101b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_PUT_START_FAILED BIT(6) 102b5b5b320SKhalil Blaiech /* Clock toggle completed. */ 103b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_CLK_TOGGLE_DONE BIT(7) 104b5b5b320SKhalil Blaiech /* Transfer timeout occurred. */ 105b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_M_FW_TIMEOUT BIT(8) 106b5b5b320SKhalil Blaiech /* Master busy bit reset. */ 107b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_M_GW_BUSY_FALL BIT(9) 108b5b5b320SKhalil Blaiech 109b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_MASTER_ARBITER_BITS_MASK GENMASK(9, 0) 110b5b5b320SKhalil Blaiech 111b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_MASTER_STATUS_ERROR \ 112b5b5b320SKhalil Blaiech (MLXBF_I2C_CAUSE_M_ARBITRATION_LOST | \ 113b5b5b320SKhalil Blaiech MLXBF_I2C_CAUSE_UNEXPECTED_START | \ 114b5b5b320SKhalil Blaiech MLXBF_I2C_CAUSE_UNEXPECTED_STOP | \ 115b5b5b320SKhalil Blaiech MLXBF_I2C_CAUSE_PUT_STOP_FAILED | \ 116b5b5b320SKhalil Blaiech MLXBF_I2C_CAUSE_PUT_START_FAILED | \ 117b5b5b320SKhalil Blaiech MLXBF_I2C_CAUSE_CLK_TOGGLE_DONE | \ 118b5b5b320SKhalil Blaiech MLXBF_I2C_CAUSE_M_FW_TIMEOUT) 119b5b5b320SKhalil Blaiech 120b5b5b320SKhalil Blaiech /* 121b5b5b320SKhalil Blaiech * Slave cause status flags. Note that those bits might be considered 122b5b5b320SKhalil Blaiech * as interrupt enabled bits. 123b5b5b320SKhalil Blaiech */ 124b5b5b320SKhalil Blaiech 125b5b5b320SKhalil Blaiech /* Write transaction received successfully. */ 126b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_WRITE_SUCCESS BIT(0) 127b5b5b320SKhalil Blaiech /* Read transaction received, waiting for response. */ 128b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_READ_WAIT_FW_RESPONSE BIT(13) 129b5b5b320SKhalil Blaiech /* Slave busy bit reset. */ 130b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_S_GW_BUSY_FALL BIT(18) 131b5b5b320SKhalil Blaiech 132b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_SLAVE_ARBITER_BITS_MASK GENMASK(20, 0) 133b5b5b320SKhalil Blaiech 134b5b5b320SKhalil Blaiech /* Cause coalesce registers. */ 135b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_COALESCE_0 0x00 136b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_COALESCE_1 0x04 137b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_COALESCE_2 0x08 138b5b5b320SKhalil Blaiech 139b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_TYU_SLAVE_BIT MLXBF_I2C_SMBUS_MAX 140b5b5b320SKhalil Blaiech #define MLXBF_I2C_CAUSE_YU_SLAVE_BIT 1 141b5b5b320SKhalil Blaiech 142b5b5b320SKhalil Blaiech /* Functional enable register. */ 143b5b5b320SKhalil Blaiech #define MLXBF_I2C_GPIO_0_FUNC_EN_0 0x28 144b5b5b320SKhalil Blaiech /* Force OE enable register. */ 145b5b5b320SKhalil Blaiech #define MLXBF_I2C_GPIO_0_FORCE_OE_EN 0x30 146b5b5b320SKhalil Blaiech /* 147b5b5b320SKhalil Blaiech * Note that Smbus GWs are on GPIOs 30:25. Two pins are used to control 148b5b5b320SKhalil Blaiech * SDA/SCL lines: 149b5b5b320SKhalil Blaiech * 150b5b5b320SKhalil Blaiech * SMBUS GW0 -> bits[26:25] 151b5b5b320SKhalil Blaiech * SMBUS GW1 -> bits[28:27] 152b5b5b320SKhalil Blaiech * SMBUS GW2 -> bits[30:29] 153b5b5b320SKhalil Blaiech */ 154b5b5b320SKhalil Blaiech #define MLXBF_I2C_GPIO_SMBUS_GW_PINS(num) (25 + ((num) << 1)) 155b5b5b320SKhalil Blaiech 156b5b5b320SKhalil Blaiech /* Note that gw_id can be 0,1 or 2. */ 157b5b5b320SKhalil Blaiech #define MLXBF_I2C_GPIO_SMBUS_GW_MASK(num) \ 158b5b5b320SKhalil Blaiech (0xffffffff & (~(0x3 << MLXBF_I2C_GPIO_SMBUS_GW_PINS(num)))) 159b5b5b320SKhalil Blaiech 160b5b5b320SKhalil Blaiech #define MLXBF_I2C_GPIO_SMBUS_GW_RESET_PINS(num, val) \ 161b5b5b320SKhalil Blaiech ((val) & MLXBF_I2C_GPIO_SMBUS_GW_MASK(num)) 162b5b5b320SKhalil Blaiech 163b5b5b320SKhalil Blaiech #define MLXBF_I2C_GPIO_SMBUS_GW_ASSERT_PINS(num, val) \ 164b5b5b320SKhalil Blaiech ((val) | (0x3 << MLXBF_I2C_GPIO_SMBUS_GW_PINS(num))) 165b5b5b320SKhalil Blaiech 166b5b5b320SKhalil Blaiech /* SMBus timing parameters. */ 167b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_TIMER_SCL_LOW_SCL_HIGH 0x00 168b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_TIMER_FALL_RISE_SPIKE 0x04 169b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_TIMER_THOLD 0x08 170b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_TIMER_TSETUP_START_STOP 0x0c 171b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_TIMER_TSETUP_DATA 0x10 172b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_THIGH_MAX_TBUF 0x14 173b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_SCL_LOW_TIMEOUT 0x18 174b5b5b320SKhalil Blaiech 175b5b5b320SKhalil Blaiech /* 176b5b5b320SKhalil Blaiech * Defines SMBus operating frequency and core clock frequency. 177b5b5b320SKhalil Blaiech * According to ADB files, default values are compliant to 100KHz SMBus 178b5b5b320SKhalil Blaiech * @ 400MHz core clock. The driver should be able to calculate core 179b5b5b320SKhalil Blaiech * frequency based on PLL parameters. 180b5b5b320SKhalil Blaiech */ 181b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_FREQ MLXBF_I2C_TYU_PLL_OUT_FREQ 182b5b5b320SKhalil Blaiech 183b5b5b320SKhalil Blaiech /* Core PLL TYU configuration. */ 184b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_F_TYU_MASK GENMASK(12, 0) 185b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK GENMASK(3, 0) 186b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_R_TYU_MASK GENMASK(5, 0) 187b5b5b320SKhalil Blaiech 188b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT 3 189b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT 16 190b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT 20 191b5b5b320SKhalil Blaiech 192b5b5b320SKhalil Blaiech /* Core PLL YU configuration. */ 193b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_F_YU_MASK GENMASK(25, 0) 194b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_OD_YU_MASK GENMASK(3, 0) 195b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_R_YU_MASK GENMASK(5, 0) 196b5b5b320SKhalil Blaiech 197b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT 0 198b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT 1 199b5b5b320SKhalil Blaiech #define MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT 26 200b5b5b320SKhalil Blaiech 201b5b5b320SKhalil Blaiech /* Core PLL frequency. */ 202b5b5b320SKhalil Blaiech static u64 mlxbf_i2c_corepll_frequency; 203b5b5b320SKhalil Blaiech 204b5b5b320SKhalil Blaiech /* SMBus Master GW. */ 205b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_MASTER_GW 0x200 206b5b5b320SKhalil Blaiech /* Number of bytes received and sent. */ 207b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_RS_BYTES 0x300 208b5b5b320SKhalil Blaiech /* Packet error check (PEC) value. */ 209b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_MASTER_PEC 0x304 210b5b5b320SKhalil Blaiech /* Status bits (ACK/NACK/FW Timeout). */ 211b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_MASTER_STATUS 0x308 212b5b5b320SKhalil Blaiech /* SMbus Master Finite State Machine. */ 213b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_MASTER_FSM 0x310 214b5b5b320SKhalil Blaiech 215b5b5b320SKhalil Blaiech /* 216b5b5b320SKhalil Blaiech * When enabled, the master will issue a stop condition in case of 217b5b5b320SKhalil Blaiech * timeout while waiting for FW response. 218b5b5b320SKhalil Blaiech */ 219b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_EN_FW_TIMEOUT 0x31c 220b5b5b320SKhalil Blaiech 221b5b5b320SKhalil Blaiech /* SMBus master GW control bits offset in MLXBF_I2C_SMBUS_MASTER_GW[31:3]. */ 222b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_LOCK_BIT BIT(31) /* Lock bit. */ 223b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_BUSY_BIT BIT(30) /* Busy bit. */ 224b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_START_BIT BIT(29) /* Control start. */ 225b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_CTL_WRITE_BIT BIT(28) /* Control write phase. */ 226b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_CTL_READ_BIT BIT(19) /* Control read phase. */ 227b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_STOP_BIT BIT(3) /* Control stop. */ 228b5b5b320SKhalil Blaiech 229b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_ENABLE \ 230b5b5b320SKhalil Blaiech (MLXBF_I2C_MASTER_LOCK_BIT | MLXBF_I2C_MASTER_BUSY_BIT | \ 231b5b5b320SKhalil Blaiech MLXBF_I2C_MASTER_START_BIT | MLXBF_I2C_MASTER_STOP_BIT) 232b5b5b320SKhalil Blaiech 233b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_ENABLE_WRITE \ 234b5b5b320SKhalil Blaiech (MLXBF_I2C_MASTER_ENABLE | MLXBF_I2C_MASTER_CTL_WRITE_BIT) 235b5b5b320SKhalil Blaiech 236b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_ENABLE_READ \ 237b5b5b320SKhalil Blaiech (MLXBF_I2C_MASTER_ENABLE | MLXBF_I2C_MASTER_CTL_READ_BIT) 238b5b5b320SKhalil Blaiech 239b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_SLV_ADDR_SHIFT 12 /* Slave address shift. */ 240b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_WRITE_SHIFT 21 /* Control write bytes shift. */ 241b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_SEND_PEC_SHIFT 20 /* Send PEC byte shift. */ 242b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_PARSE_EXP_SHIFT 11 /* Parse expected bytes shift. */ 243b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_READ_SHIFT 4 /* Control read bytes shift. */ 244b5b5b320SKhalil Blaiech 245b5b5b320SKhalil Blaiech /* SMBus master GW Data descriptor. */ 246b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_DATA_DESC_ADDR 0x280 247b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_DATA_DESC_SIZE 0x80 /* Size in bytes. */ 248b5b5b320SKhalil Blaiech 249b5b5b320SKhalil Blaiech /* Maximum bytes to read/write per SMBus transaction. */ 250b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_DATA_R_LENGTH MLXBF_I2C_MASTER_DATA_DESC_SIZE 251b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASTER_DATA_W_LENGTH (MLXBF_I2C_MASTER_DATA_DESC_SIZE - 1) 252b5b5b320SKhalil Blaiech 253b5b5b320SKhalil Blaiech /* All bytes were transmitted. */ 254b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_STATUS_BYTE_CNT_DONE BIT(0) 255b5b5b320SKhalil Blaiech /* NACK received. */ 256b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_STATUS_NACK_RCV BIT(1) 257b5b5b320SKhalil Blaiech /* Slave's byte count >128 bytes. */ 258b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_STATUS_READ_ERR BIT(2) 259b5b5b320SKhalil Blaiech /* Timeout occurred. */ 260b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_STATUS_FW_TIMEOUT BIT(3) 261b5b5b320SKhalil Blaiech 262b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_MASTER_STATUS_MASK GENMASK(3, 0) 263b5b5b320SKhalil Blaiech 264b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_MASTER_STATUS_ERROR \ 265b5b5b320SKhalil Blaiech (MLXBF_I2C_SMBUS_STATUS_NACK_RCV | \ 266b5b5b320SKhalil Blaiech MLXBF_I2C_SMBUS_STATUS_READ_ERR | \ 267b5b5b320SKhalil Blaiech MLXBF_I2C_SMBUS_STATUS_FW_TIMEOUT) 268b5b5b320SKhalil Blaiech 269b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_MASTER_FSM_STOP_MASK BIT(31) 270b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_MASTER_FSM_PS_STATE_MASK BIT(15) 271b5b5b320SKhalil Blaiech 272b5b5b320SKhalil Blaiech /* SMBus slave GW. */ 273b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_SLAVE_GW 0x400 274b5b5b320SKhalil Blaiech /* Number of bytes received and sent from/to master. */ 275b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES 0x500 276b5b5b320SKhalil Blaiech /* Packet error check (PEC) value. */ 277b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_SLAVE_PEC 0x504 278b5b5b320SKhalil Blaiech /* SMBus slave Finite State Machine (FSM). */ 279b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_SLAVE_FSM 0x510 280b5b5b320SKhalil Blaiech /* 281b5b5b320SKhalil Blaiech * Should be set when all raised causes handled, and cleared by HW on 282b5b5b320SKhalil Blaiech * every new cause. 283b5b5b320SKhalil Blaiech */ 284b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_SLAVE_READY 0x52c 285b5b5b320SKhalil Blaiech 286b5b5b320SKhalil Blaiech /* SMBus slave GW control bits offset in MLXBF_I2C_SMBUS_SLAVE_GW[31:19]. */ 287b5b5b320SKhalil Blaiech #define MLXBF_I2C_SLAVE_BUSY_BIT BIT(30) /* Busy bit. */ 288b5b5b320SKhalil Blaiech #define MLXBF_I2C_SLAVE_WRITE_BIT BIT(29) /* Control write enable. */ 289b5b5b320SKhalil Blaiech 290b5b5b320SKhalil Blaiech #define MLXBF_I2C_SLAVE_ENABLE \ 291b5b5b320SKhalil Blaiech (MLXBF_I2C_SLAVE_BUSY_BIT | MLXBF_I2C_SLAVE_WRITE_BIT) 292b5b5b320SKhalil Blaiech 293b5b5b320SKhalil Blaiech #define MLXBF_I2C_SLAVE_WRITE_BYTES_SHIFT 22 /* Number of bytes to write. */ 294b5b5b320SKhalil Blaiech #define MLXBF_I2C_SLAVE_SEND_PEC_SHIFT 21 /* Send PEC byte shift. */ 295b5b5b320SKhalil Blaiech 296b5b5b320SKhalil Blaiech /* SMBus slave GW Data descriptor. */ 297b5b5b320SKhalil Blaiech #define MLXBF_I2C_SLAVE_DATA_DESC_ADDR 0x480 298b5b5b320SKhalil Blaiech #define MLXBF_I2C_SLAVE_DATA_DESC_SIZE 0x80 /* Size in bytes. */ 299b5b5b320SKhalil Blaiech 300b5b5b320SKhalil Blaiech /* SMbus slave configuration registers. */ 301b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG 0x514 302b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_SLAVE_ADDR_CNT 16 303b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_SLAVE_ADDR_EN_BIT 7 304b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_SLAVE_ADDR_MASK GENMASK(6, 0) 305b5b5b320SKhalil Blaiech 306b5b5b320SKhalil Blaiech #define MLXBF_I2C_SLAVE_ADDR_ENABLED(addr) \ 307b5b5b320SKhalil Blaiech ((addr) & (1 << MLXBF_I2C_SMBUS_SLAVE_ADDR_EN_BIT)) 308b5b5b320SKhalil Blaiech 309b5b5b320SKhalil Blaiech /* 310b5b5b320SKhalil Blaiech * Timeout is given in microsends. Note also that timeout handling is not 311b5b5b320SKhalil Blaiech * exact. 312b5b5b320SKhalil Blaiech */ 313b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_TIMEOUT (300 * 1000) /* 300ms */ 314b5b5b320SKhalil Blaiech 315b5b5b320SKhalil Blaiech /* Encapsulates timing parameters. */ 316b5b5b320SKhalil Blaiech struct mlxbf_i2c_timings { 317b5b5b320SKhalil Blaiech u16 scl_high; /* Clock high period. */ 318b5b5b320SKhalil Blaiech u16 scl_low; /* Clock low period. */ 319b5b5b320SKhalil Blaiech u8 sda_rise; /* Data rise time. */ 320b5b5b320SKhalil Blaiech u8 sda_fall; /* Data fall time. */ 321b5b5b320SKhalil Blaiech u8 scl_rise; /* Clock rise time. */ 322b5b5b320SKhalil Blaiech u8 scl_fall; /* Clock fall time. */ 323b5b5b320SKhalil Blaiech u16 hold_start; /* Hold time after (REPEATED) START. */ 324b5b5b320SKhalil Blaiech u16 hold_data; /* Data hold time. */ 325b5b5b320SKhalil Blaiech u16 setup_start; /* REPEATED START condition setup time. */ 326b5b5b320SKhalil Blaiech u16 setup_stop; /* STOP condition setup time. */ 327b5b5b320SKhalil Blaiech u16 setup_data; /* Data setup time. */ 328b5b5b320SKhalil Blaiech u16 pad; /* Padding. */ 329b5b5b320SKhalil Blaiech u16 buf; /* Bus free time between STOP and START. */ 330b5b5b320SKhalil Blaiech u16 thigh_max; /* Thigh max. */ 331b5b5b320SKhalil Blaiech u32 timeout; /* Detect clock low timeout. */ 332b5b5b320SKhalil Blaiech }; 333b5b5b320SKhalil Blaiech 334b5b5b320SKhalil Blaiech enum { 335b5b5b320SKhalil Blaiech MLXBF_I2C_F_READ = BIT(0), 336b5b5b320SKhalil Blaiech MLXBF_I2C_F_WRITE = BIT(1), 337b5b5b320SKhalil Blaiech MLXBF_I2C_F_NORESTART = BIT(3), 338b5b5b320SKhalil Blaiech MLXBF_I2C_F_SMBUS_OPERATION = BIT(4), 339b5b5b320SKhalil Blaiech MLXBF_I2C_F_SMBUS_BLOCK = BIT(5), 340b5b5b320SKhalil Blaiech MLXBF_I2C_F_SMBUS_PEC = BIT(6), 341b5b5b320SKhalil Blaiech MLXBF_I2C_F_SMBUS_PROCESS_CALL = BIT(7), 342b5b5b320SKhalil Blaiech }; 343b5b5b320SKhalil Blaiech 344b5b5b320SKhalil Blaiech struct mlxbf_i2c_smbus_operation { 345b5b5b320SKhalil Blaiech u32 flags; 346b5b5b320SKhalil Blaiech u32 length; /* Buffer length in bytes. */ 347b5b5b320SKhalil Blaiech u8 *buffer; 348b5b5b320SKhalil Blaiech }; 349b5b5b320SKhalil Blaiech 350b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_OP_CNT_1 1 351b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_OP_CNT_2 2 352b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_OP_CNT_3 3 353b5b5b320SKhalil Blaiech #define MLXBF_I2C_SMBUS_MAX_OP_CNT MLXBF_I2C_SMBUS_OP_CNT_3 354b5b5b320SKhalil Blaiech 355b5b5b320SKhalil Blaiech struct mlxbf_i2c_smbus_request { 356b5b5b320SKhalil Blaiech u8 slave; 357b5b5b320SKhalil Blaiech u8 operation_cnt; 358b5b5b320SKhalil Blaiech struct mlxbf_i2c_smbus_operation operation[MLXBF_I2C_SMBUS_MAX_OP_CNT]; 359b5b5b320SKhalil Blaiech }; 360b5b5b320SKhalil Blaiech 361b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource { 362b5b5b320SKhalil Blaiech void __iomem *io; 363b5b5b320SKhalil Blaiech struct resource *params; 364b5b5b320SKhalil Blaiech struct mutex *lock; /* Mutex to protect mlxbf_i2c_resource. */ 365b5b5b320SKhalil Blaiech u8 type; 366b5b5b320SKhalil Blaiech }; 367b5b5b320SKhalil Blaiech 368b5b5b320SKhalil Blaiech /* List of chip resources that are being accessed by the driver. */ 369b5b5b320SKhalil Blaiech enum { 370b5b5b320SKhalil Blaiech MLXBF_I2C_SMBUS_RES, 371b5b5b320SKhalil Blaiech MLXBF_I2C_MST_CAUSE_RES, 372b5b5b320SKhalil Blaiech MLXBF_I2C_SLV_CAUSE_RES, 373b5b5b320SKhalil Blaiech MLXBF_I2C_COALESCE_RES, 374b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_RES, 375b5b5b320SKhalil Blaiech MLXBF_I2C_GPIO_RES, 376b5b5b320SKhalil Blaiech MLXBF_I2C_END_RES, 377b5b5b320SKhalil Blaiech }; 378b5b5b320SKhalil Blaiech 379b5b5b320SKhalil Blaiech /* Helper macro to define an I2C resource parameters. */ 380b5b5b320SKhalil Blaiech #define MLXBF_I2C_RES_PARAMS(addr, size, str) \ 381b5b5b320SKhalil Blaiech { \ 382b5b5b320SKhalil Blaiech .start = (addr), \ 383b5b5b320SKhalil Blaiech .end = (addr) + (size) - 1, \ 384b5b5b320SKhalil Blaiech .name = (str) \ 385b5b5b320SKhalil Blaiech } 386b5b5b320SKhalil Blaiech 387b5b5b320SKhalil Blaiech static struct resource mlxbf_i2c_coalesce_tyu_params = 388b5b5b320SKhalil Blaiech MLXBF_I2C_RES_PARAMS(MLXBF_I2C_COALESCE_TYU_ADDR, 389b5b5b320SKhalil Blaiech MLXBF_I2C_COALESCE_TYU_SIZE, 390b5b5b320SKhalil Blaiech "COALESCE_MEM"); 391b5b5b320SKhalil Blaiech static struct resource mlxbf_i2c_corepll_tyu_params = 392b5b5b320SKhalil Blaiech MLXBF_I2C_RES_PARAMS(MLXBF_I2C_COREPLL_TYU_ADDR, 393b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_TYU_SIZE, 394b5b5b320SKhalil Blaiech "COREPLL_MEM"); 395b5b5b320SKhalil Blaiech static struct resource mlxbf_i2c_corepll_yu_params = 396b5b5b320SKhalil Blaiech MLXBF_I2C_RES_PARAMS(MLXBF_I2C_COREPLL_YU_ADDR, 397b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_YU_SIZE, 398b5b5b320SKhalil Blaiech "COREPLL_MEM"); 399b5b5b320SKhalil Blaiech static struct resource mlxbf_i2c_gpio_tyu_params = 400b5b5b320SKhalil Blaiech MLXBF_I2C_RES_PARAMS(MLXBF_I2C_GPIO_TYU_ADDR, 401b5b5b320SKhalil Blaiech MLXBF_I2C_GPIO_TYU_SIZE, 402b5b5b320SKhalil Blaiech "GPIO_MEM"); 403b5b5b320SKhalil Blaiech 404b5b5b320SKhalil Blaiech static struct mutex mlxbf_i2c_coalesce_lock; 405b5b5b320SKhalil Blaiech static struct mutex mlxbf_i2c_corepll_lock; 406b5b5b320SKhalil Blaiech static struct mutex mlxbf_i2c_gpio_lock; 407b5b5b320SKhalil Blaiech 408b5b5b320SKhalil Blaiech /* Mellanox BlueField chip type. */ 409b5b5b320SKhalil Blaiech enum mlxbf_i2c_chip_type { 410b5b5b320SKhalil Blaiech MLXBF_I2C_CHIP_TYPE_1, /* Mellanox BlueField-1 chip. */ 411b5b5b320SKhalil Blaiech MLXBF_I2C_CHIP_TYPE_2, /* Mallanox BlueField-2 chip. */ 412b5b5b320SKhalil Blaiech }; 413b5b5b320SKhalil Blaiech 414b5b5b320SKhalil Blaiech struct mlxbf_i2c_chip_info { 415b5b5b320SKhalil Blaiech enum mlxbf_i2c_chip_type type; 416b5b5b320SKhalil Blaiech /* Chip shared resources that are being used by the I2C controller. */ 417b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *shared_res[MLXBF_I2C_SHARED_RES_MAX]; 418b5b5b320SKhalil Blaiech 419b5b5b320SKhalil Blaiech /* Callback to calculate the core PLL frequency. */ 420b5b5b320SKhalil Blaiech u64 (*calculate_freq)(struct mlxbf_i2c_resource *corepll_res); 421b5b5b320SKhalil Blaiech }; 422b5b5b320SKhalil Blaiech 423b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv { 424b5b5b320SKhalil Blaiech const struct mlxbf_i2c_chip_info *chip; 425b5b5b320SKhalil Blaiech struct i2c_adapter adap; 426b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *smbus; 427b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *mst_cause; 428b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *slv_cause; 429b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *coalesce; 430b5b5b320SKhalil Blaiech u64 frequency; /* Core frequency in Hz. */ 431b5b5b320SKhalil Blaiech int bus; /* Physical bus identifier. */ 432b5b5b320SKhalil Blaiech int irq; 433b5b5b320SKhalil Blaiech struct i2c_client *slave; 434b5b5b320SKhalil Blaiech }; 435b5b5b320SKhalil Blaiech 436b5b5b320SKhalil Blaiech static struct mlxbf_i2c_resource mlxbf_i2c_coalesce_res[] = { 437b5b5b320SKhalil Blaiech [MLXBF_I2C_CHIP_TYPE_1] = { 438b5b5b320SKhalil Blaiech .params = &mlxbf_i2c_coalesce_tyu_params, 439b5b5b320SKhalil Blaiech .lock = &mlxbf_i2c_coalesce_lock, 440b5b5b320SKhalil Blaiech .type = MLXBF_I2C_COALESCE_RES 441b5b5b320SKhalil Blaiech }, 442b5b5b320SKhalil Blaiech {} 443b5b5b320SKhalil Blaiech }; 444b5b5b320SKhalil Blaiech 445b5b5b320SKhalil Blaiech static struct mlxbf_i2c_resource mlxbf_i2c_corepll_res[] = { 446b5b5b320SKhalil Blaiech [MLXBF_I2C_CHIP_TYPE_1] = { 447b5b5b320SKhalil Blaiech .params = &mlxbf_i2c_corepll_tyu_params, 448b5b5b320SKhalil Blaiech .lock = &mlxbf_i2c_corepll_lock, 449b5b5b320SKhalil Blaiech .type = MLXBF_I2C_COREPLL_RES 450b5b5b320SKhalil Blaiech }, 451b5b5b320SKhalil Blaiech [MLXBF_I2C_CHIP_TYPE_2] = { 452b5b5b320SKhalil Blaiech .params = &mlxbf_i2c_corepll_yu_params, 453b5b5b320SKhalil Blaiech .lock = &mlxbf_i2c_corepll_lock, 454b5b5b320SKhalil Blaiech .type = MLXBF_I2C_COREPLL_RES, 455b5b5b320SKhalil Blaiech } 456b5b5b320SKhalil Blaiech }; 457b5b5b320SKhalil Blaiech 458b5b5b320SKhalil Blaiech static struct mlxbf_i2c_resource mlxbf_i2c_gpio_res[] = { 459b5b5b320SKhalil Blaiech [MLXBF_I2C_CHIP_TYPE_1] = { 460b5b5b320SKhalil Blaiech .params = &mlxbf_i2c_gpio_tyu_params, 461b5b5b320SKhalil Blaiech .lock = &mlxbf_i2c_gpio_lock, 462b5b5b320SKhalil Blaiech .type = MLXBF_I2C_GPIO_RES 463b5b5b320SKhalil Blaiech }, 464b5b5b320SKhalil Blaiech {} 465b5b5b320SKhalil Blaiech }; 466b5b5b320SKhalil Blaiech 467b5b5b320SKhalil Blaiech static u8 mlxbf_i2c_bus_count; 468b5b5b320SKhalil Blaiech 469b5b5b320SKhalil Blaiech static struct mutex mlxbf_i2c_bus_lock; 470b5b5b320SKhalil Blaiech 471b5b5b320SKhalil Blaiech /* Polling frequency in microseconds. */ 472b5b5b320SKhalil Blaiech #define MLXBF_I2C_POLL_FREQ_IN_USEC 200 473b5b5b320SKhalil Blaiech 474b5b5b320SKhalil Blaiech #define MLXBF_I2C_SHIFT_0 0 475b5b5b320SKhalil Blaiech #define MLXBF_I2C_SHIFT_8 8 476b5b5b320SKhalil Blaiech #define MLXBF_I2C_SHIFT_16 16 477b5b5b320SKhalil Blaiech #define MLXBF_I2C_SHIFT_24 24 478b5b5b320SKhalil Blaiech 479b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASK_8 GENMASK(7, 0) 480b5b5b320SKhalil Blaiech #define MLXBF_I2C_MASK_16 GENMASK(15, 0) 481b5b5b320SKhalil Blaiech 482b5b5b320SKhalil Blaiech #define MLXBF_I2C_FREQUENCY_1GHZ 1000000000 483b5b5b320SKhalil Blaiech 484b5b5b320SKhalil Blaiech /* 485b5b5b320SKhalil Blaiech * Function to poll a set of bits at a specific address; it checks whether 486b5b5b320SKhalil Blaiech * the bits are equal to zero when eq_zero is set to 'true', and not equal 487b5b5b320SKhalil Blaiech * to zero when eq_zero is set to 'false'. 488b5b5b320SKhalil Blaiech * Note that the timeout is given in microseconds. 489b5b5b320SKhalil Blaiech */ 490b5b5b320SKhalil Blaiech static u32 mlxbf_smbus_poll(void __iomem *io, u32 addr, u32 mask, 491b5b5b320SKhalil Blaiech bool eq_zero, u32 timeout) 492b5b5b320SKhalil Blaiech { 493b5b5b320SKhalil Blaiech u32 bits; 494b5b5b320SKhalil Blaiech 495b5b5b320SKhalil Blaiech timeout = (timeout / MLXBF_I2C_POLL_FREQ_IN_USEC) + 1; 496b5b5b320SKhalil Blaiech 497b5b5b320SKhalil Blaiech do { 4984b19d806SKhalil Blaiech bits = readl(io + addr) & mask; 499b5b5b320SKhalil Blaiech if (eq_zero ? bits == 0 : bits != 0) 500b5b5b320SKhalil Blaiech return eq_zero ? 1 : bits; 501b5b5b320SKhalil Blaiech udelay(MLXBF_I2C_POLL_FREQ_IN_USEC); 502b5b5b320SKhalil Blaiech } while (timeout-- != 0); 503b5b5b320SKhalil Blaiech 504b5b5b320SKhalil Blaiech return 0; 505b5b5b320SKhalil Blaiech } 506b5b5b320SKhalil Blaiech 507b5b5b320SKhalil Blaiech /* 508b5b5b320SKhalil Blaiech * SW must make sure that the SMBus Master GW is idle before starting 509b5b5b320SKhalil Blaiech * a transaction. Accordingly, this function polls the Master FSM stop 510b5b5b320SKhalil Blaiech * bit; it returns false when the bit is asserted, true if not. 511b5b5b320SKhalil Blaiech */ 512b5b5b320SKhalil Blaiech static bool mlxbf_smbus_master_wait_for_idle(struct mlxbf_i2c_priv *priv) 513b5b5b320SKhalil Blaiech { 514b5b5b320SKhalil Blaiech u32 mask = MLXBF_I2C_SMBUS_MASTER_FSM_STOP_MASK; 515b5b5b320SKhalil Blaiech u32 addr = MLXBF_I2C_SMBUS_MASTER_FSM; 516b5b5b320SKhalil Blaiech u32 timeout = MLXBF_I2C_SMBUS_TIMEOUT; 517b5b5b320SKhalil Blaiech 518b5b5b320SKhalil Blaiech if (mlxbf_smbus_poll(priv->smbus->io, addr, mask, true, timeout)) 519b5b5b320SKhalil Blaiech return true; 520b5b5b320SKhalil Blaiech 521b5b5b320SKhalil Blaiech return false; 522b5b5b320SKhalil Blaiech } 523b5b5b320SKhalil Blaiech 524b5b5b320SKhalil Blaiech static bool mlxbf_i2c_smbus_transaction_success(u32 master_status, 525b5b5b320SKhalil Blaiech u32 cause_status) 526b5b5b320SKhalil Blaiech { 527b5b5b320SKhalil Blaiech /* 528b5b5b320SKhalil Blaiech * When transaction ended with STOP, all bytes were transmitted, 529b5b5b320SKhalil Blaiech * and no NACK received, then the transaction ended successfully. 530b5b5b320SKhalil Blaiech * On the other hand, when the GW is configured with the stop bit 531b5b5b320SKhalil Blaiech * de-asserted then the SMBus expects the following GW configuration 532b5b5b320SKhalil Blaiech * for transfer continuation. 533b5b5b320SKhalil Blaiech */ 534b5b5b320SKhalil Blaiech if ((cause_status & MLXBF_I2C_CAUSE_WAIT_FOR_FW_DATA) || 535b5b5b320SKhalil Blaiech ((cause_status & MLXBF_I2C_CAUSE_TRANSACTION_ENDED) && 536b5b5b320SKhalil Blaiech (master_status & MLXBF_I2C_SMBUS_STATUS_BYTE_CNT_DONE) && 537b5b5b320SKhalil Blaiech !(master_status & MLXBF_I2C_SMBUS_STATUS_NACK_RCV))) 538b5b5b320SKhalil Blaiech return true; 539b5b5b320SKhalil Blaiech 540b5b5b320SKhalil Blaiech return false; 541b5b5b320SKhalil Blaiech } 542b5b5b320SKhalil Blaiech 543b5b5b320SKhalil Blaiech /* 544b5b5b320SKhalil Blaiech * Poll SMBus master status and return transaction status, 545b5b5b320SKhalil Blaiech * i.e. whether succeeded or failed. I2C and SMBus fault codes 546b5b5b320SKhalil Blaiech * are returned as negative numbers from most calls, with zero 547b5b5b320SKhalil Blaiech * or some positive number indicating a non-fault return. 548b5b5b320SKhalil Blaiech */ 549b5b5b320SKhalil Blaiech static int mlxbf_i2c_smbus_check_status(struct mlxbf_i2c_priv *priv) 550b5b5b320SKhalil Blaiech { 551b5b5b320SKhalil Blaiech u32 master_status_bits; 552b5b5b320SKhalil Blaiech u32 cause_status_bits; 553b5b5b320SKhalil Blaiech 554b5b5b320SKhalil Blaiech /* 555b5b5b320SKhalil Blaiech * GW busy bit is raised by the driver and cleared by the HW 556b5b5b320SKhalil Blaiech * when the transaction is completed. The busy bit is a good 557b5b5b320SKhalil Blaiech * indicator of transaction status. So poll the busy bit, and 558b5b5b320SKhalil Blaiech * then read the cause and master status bits to determine if 559b5b5b320SKhalil Blaiech * errors occurred during the transaction. 560b5b5b320SKhalil Blaiech */ 561b5b5b320SKhalil Blaiech mlxbf_smbus_poll(priv->smbus->io, MLXBF_I2C_SMBUS_MASTER_GW, 562b5b5b320SKhalil Blaiech MLXBF_I2C_MASTER_BUSY_BIT, true, 563b5b5b320SKhalil Blaiech MLXBF_I2C_SMBUS_TIMEOUT); 564b5b5b320SKhalil Blaiech 565b5b5b320SKhalil Blaiech /* Read cause status bits. */ 5664b19d806SKhalil Blaiech cause_status_bits = readl(priv->mst_cause->io + 567b5b5b320SKhalil Blaiech MLXBF_I2C_CAUSE_ARBITER); 568b5b5b320SKhalil Blaiech cause_status_bits &= MLXBF_I2C_CAUSE_MASTER_ARBITER_BITS_MASK; 569b5b5b320SKhalil Blaiech 570b5b5b320SKhalil Blaiech /* 571b5b5b320SKhalil Blaiech * Parse both Cause and Master GW bits, then return transaction status. 572b5b5b320SKhalil Blaiech */ 573b5b5b320SKhalil Blaiech 5744b19d806SKhalil Blaiech master_status_bits = readl(priv->smbus->io + 575b5b5b320SKhalil Blaiech MLXBF_I2C_SMBUS_MASTER_STATUS); 576b5b5b320SKhalil Blaiech master_status_bits &= MLXBF_I2C_SMBUS_MASTER_STATUS_MASK; 577b5b5b320SKhalil Blaiech 578b5b5b320SKhalil Blaiech if (mlxbf_i2c_smbus_transaction_success(master_status_bits, 579b5b5b320SKhalil Blaiech cause_status_bits)) 580b5b5b320SKhalil Blaiech return 0; 581b5b5b320SKhalil Blaiech 582b5b5b320SKhalil Blaiech /* 583b5b5b320SKhalil Blaiech * In case of timeout on GW busy, the ISR will clear busy bit but 584b5b5b320SKhalil Blaiech * transaction ended bits cause will not be set so the transaction 585b5b5b320SKhalil Blaiech * fails. Then, we must check Master GW status bits. 586b5b5b320SKhalil Blaiech */ 587b5b5b320SKhalil Blaiech if ((master_status_bits & MLXBF_I2C_SMBUS_MASTER_STATUS_ERROR) && 588b5b5b320SKhalil Blaiech (cause_status_bits & (MLXBF_I2C_CAUSE_TRANSACTION_ENDED | 589b5b5b320SKhalil Blaiech MLXBF_I2C_CAUSE_M_GW_BUSY_FALL))) 590b5b5b320SKhalil Blaiech return -EIO; 591b5b5b320SKhalil Blaiech 592b5b5b320SKhalil Blaiech if (cause_status_bits & MLXBF_I2C_CAUSE_MASTER_STATUS_ERROR) 593b5b5b320SKhalil Blaiech return -EAGAIN; 594b5b5b320SKhalil Blaiech 595b5b5b320SKhalil Blaiech return -ETIMEDOUT; 596b5b5b320SKhalil Blaiech } 597b5b5b320SKhalil Blaiech 598b5b5b320SKhalil Blaiech static void mlxbf_i2c_smbus_write_data(struct mlxbf_i2c_priv *priv, 599b5b5b320SKhalil Blaiech const u8 *data, u8 length, u32 addr) 600b5b5b320SKhalil Blaiech { 601b5b5b320SKhalil Blaiech u8 offset, aligned_length; 602b5b5b320SKhalil Blaiech u32 data32; 603b5b5b320SKhalil Blaiech 604b5b5b320SKhalil Blaiech aligned_length = round_up(length, 4); 605b5b5b320SKhalil Blaiech 6064b19d806SKhalil Blaiech /* 6074b19d806SKhalil Blaiech * Copy data bytes from 4-byte aligned source buffer. 6084b19d806SKhalil Blaiech * Data copied to the Master GW Data Descriptor MUST be shifted 6094b19d806SKhalil Blaiech * left so the data starts at the MSB of the descriptor registers 6104b19d806SKhalil Blaiech * as required by the underlying hardware. Enable byte swapping 6114b19d806SKhalil Blaiech * when writing data bytes to the 32 * 32-bit HW Data registers 6124b19d806SKhalil Blaiech * a.k.a Master GW Data Descriptor. 6134b19d806SKhalil Blaiech */ 614b5b5b320SKhalil Blaiech for (offset = 0; offset < aligned_length; offset += sizeof(u32)) { 615b5b5b320SKhalil Blaiech data32 = *((u32 *)(data + offset)); 6164b19d806SKhalil Blaiech iowrite32be(data32, priv->smbus->io + addr + offset); 617b5b5b320SKhalil Blaiech } 618b5b5b320SKhalil Blaiech } 619b5b5b320SKhalil Blaiech 620b5b5b320SKhalil Blaiech static void mlxbf_i2c_smbus_read_data(struct mlxbf_i2c_priv *priv, 621b5b5b320SKhalil Blaiech u8 *data, u8 length, u32 addr) 622b5b5b320SKhalil Blaiech { 623b5b5b320SKhalil Blaiech u32 data32, mask; 624b5b5b320SKhalil Blaiech u8 byte, offset; 625b5b5b320SKhalil Blaiech 626b5b5b320SKhalil Blaiech mask = sizeof(u32) - 1; 627b5b5b320SKhalil Blaiech 6284b19d806SKhalil Blaiech /* 6294b19d806SKhalil Blaiech * Data bytes in the Master GW Data Descriptor are shifted left 6304b19d806SKhalil Blaiech * so the data starts at the MSB of the descriptor registers as 6314b19d806SKhalil Blaiech * set by the underlying hardware. Enable byte swapping while 6324b19d806SKhalil Blaiech * reading data bytes from the 32 * 32-bit HW Data registers 6334b19d806SKhalil Blaiech * a.k.a Master GW Data Descriptor. 6344b19d806SKhalil Blaiech */ 6354b19d806SKhalil Blaiech 636b5b5b320SKhalil Blaiech for (offset = 0; offset < (length & ~mask); offset += sizeof(u32)) { 6374b19d806SKhalil Blaiech data32 = ioread32be(priv->smbus->io + addr + offset); 638b5b5b320SKhalil Blaiech *((u32 *)(data + offset)) = data32; 639b5b5b320SKhalil Blaiech } 640b5b5b320SKhalil Blaiech 641b5b5b320SKhalil Blaiech if (!(length & mask)) 642b5b5b320SKhalil Blaiech return; 643b5b5b320SKhalil Blaiech 6444b19d806SKhalil Blaiech data32 = ioread32be(priv->smbus->io + addr + offset); 645b5b5b320SKhalil Blaiech 646b5b5b320SKhalil Blaiech for (byte = 0; byte < (length & mask); byte++) { 647b5b5b320SKhalil Blaiech data[offset + byte] = data32 & GENMASK(7, 0); 648b5b5b320SKhalil Blaiech data32 = ror32(data32, MLXBF_I2C_SHIFT_8); 649b5b5b320SKhalil Blaiech } 650b5b5b320SKhalil Blaiech } 651b5b5b320SKhalil Blaiech 652b5b5b320SKhalil Blaiech static int mlxbf_i2c_smbus_enable(struct mlxbf_i2c_priv *priv, u8 slave, 653b5b5b320SKhalil Blaiech u8 len, u8 block_en, u8 pec_en, bool read) 654b5b5b320SKhalil Blaiech { 655b5b5b320SKhalil Blaiech u32 command; 656b5b5b320SKhalil Blaiech 657b5b5b320SKhalil Blaiech /* Set Master GW control word. */ 658b5b5b320SKhalil Blaiech if (read) { 659b5b5b320SKhalil Blaiech command = MLXBF_I2C_MASTER_ENABLE_READ; 660b5b5b320SKhalil Blaiech command |= rol32(len, MLXBF_I2C_MASTER_READ_SHIFT); 661b5b5b320SKhalil Blaiech } else { 662b5b5b320SKhalil Blaiech command = MLXBF_I2C_MASTER_ENABLE_WRITE; 663b5b5b320SKhalil Blaiech command |= rol32(len, MLXBF_I2C_MASTER_WRITE_SHIFT); 664b5b5b320SKhalil Blaiech } 665b5b5b320SKhalil Blaiech command |= rol32(slave, MLXBF_I2C_MASTER_SLV_ADDR_SHIFT); 666b5b5b320SKhalil Blaiech command |= rol32(block_en, MLXBF_I2C_MASTER_PARSE_EXP_SHIFT); 667b5b5b320SKhalil Blaiech command |= rol32(pec_en, MLXBF_I2C_MASTER_SEND_PEC_SHIFT); 668b5b5b320SKhalil Blaiech 669b5b5b320SKhalil Blaiech /* Clear status bits. */ 6704b19d806SKhalil Blaiech writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_STATUS); 671b5b5b320SKhalil Blaiech /* Set the cause data. */ 672*2a5be6d1SAsmaa Mnebhi writel(~0x0, priv->mst_cause->io + MLXBF_I2C_CAUSE_OR_CLEAR); 673b5b5b320SKhalil Blaiech /* Zero PEC byte. */ 6744b19d806SKhalil Blaiech writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_PEC); 675b5b5b320SKhalil Blaiech /* Zero byte count. */ 6764b19d806SKhalil Blaiech writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_RS_BYTES); 677b5b5b320SKhalil Blaiech 678b5b5b320SKhalil Blaiech /* GW activation. */ 6794b19d806SKhalil Blaiech writel(command, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_GW); 680b5b5b320SKhalil Blaiech 681b5b5b320SKhalil Blaiech /* 682b5b5b320SKhalil Blaiech * Poll master status and check status bits. An ACK is sent when 683b5b5b320SKhalil Blaiech * completing writing data to the bus (Master 'byte_count_done' bit 684b5b5b320SKhalil Blaiech * is set to 1). 685b5b5b320SKhalil Blaiech */ 686b5b5b320SKhalil Blaiech return mlxbf_i2c_smbus_check_status(priv); 687b5b5b320SKhalil Blaiech } 688b5b5b320SKhalil Blaiech 689b5b5b320SKhalil Blaiech static int 690b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, 691b5b5b320SKhalil Blaiech struct mlxbf_i2c_smbus_request *request) 692b5b5b320SKhalil Blaiech { 693b5b5b320SKhalil Blaiech u8 data_desc[MLXBF_I2C_MASTER_DATA_DESC_SIZE] = { 0 }; 694b5b5b320SKhalil Blaiech u8 op_idx, data_idx, data_len, write_len, read_len; 695b5b5b320SKhalil Blaiech struct mlxbf_i2c_smbus_operation *operation; 696b5b5b320SKhalil Blaiech u8 read_en, write_en, block_en, pec_en; 697b5b5b320SKhalil Blaiech u8 slave, flags, addr; 698b5b5b320SKhalil Blaiech u8 *read_buf; 699b5b5b320SKhalil Blaiech int ret = 0; 700b5b5b320SKhalil Blaiech 701b5b5b320SKhalil Blaiech if (request->operation_cnt > MLXBF_I2C_SMBUS_MAX_OP_CNT) 702b5b5b320SKhalil Blaiech return -EINVAL; 703b5b5b320SKhalil Blaiech 704b5b5b320SKhalil Blaiech read_buf = NULL; 705b5b5b320SKhalil Blaiech data_idx = 0; 706b5b5b320SKhalil Blaiech read_en = 0; 707b5b5b320SKhalil Blaiech write_en = 0; 708b5b5b320SKhalil Blaiech write_len = 0; 709b5b5b320SKhalil Blaiech read_len = 0; 710b5b5b320SKhalil Blaiech block_en = 0; 711b5b5b320SKhalil Blaiech pec_en = 0; 712b5b5b320SKhalil Blaiech slave = request->slave & GENMASK(6, 0); 713b5b5b320SKhalil Blaiech addr = slave << 1; 714b5b5b320SKhalil Blaiech 715b5b5b320SKhalil Blaiech /* First of all, check whether the HW is idle. */ 716b5b5b320SKhalil Blaiech if (WARN_ON(!mlxbf_smbus_master_wait_for_idle(priv))) 717b5b5b320SKhalil Blaiech return -EBUSY; 718b5b5b320SKhalil Blaiech 719b5b5b320SKhalil Blaiech /* Set first byte. */ 720b5b5b320SKhalil Blaiech data_desc[data_idx++] = addr; 721b5b5b320SKhalil Blaiech 722b5b5b320SKhalil Blaiech for (op_idx = 0; op_idx < request->operation_cnt; op_idx++) { 723b5b5b320SKhalil Blaiech operation = &request->operation[op_idx]; 724b5b5b320SKhalil Blaiech flags = operation->flags; 725b5b5b320SKhalil Blaiech 726b5b5b320SKhalil Blaiech /* 727b5b5b320SKhalil Blaiech * Note that read and write operations might be handled by a 728b5b5b320SKhalil Blaiech * single command. If the MLXBF_I2C_F_SMBUS_OPERATION is set 729b5b5b320SKhalil Blaiech * then write command byte and set the optional SMBus specific 730b5b5b320SKhalil Blaiech * bits such as block_en and pec_en. These bits MUST be 731b5b5b320SKhalil Blaiech * submitted by the first operation only. 732b5b5b320SKhalil Blaiech */ 733b5b5b320SKhalil Blaiech if (op_idx == 0 && flags & MLXBF_I2C_F_SMBUS_OPERATION) { 734b5b5b320SKhalil Blaiech block_en = flags & MLXBF_I2C_F_SMBUS_BLOCK; 735b5b5b320SKhalil Blaiech pec_en = flags & MLXBF_I2C_F_SMBUS_PEC; 736b5b5b320SKhalil Blaiech } 737b5b5b320SKhalil Blaiech 738b5b5b320SKhalil Blaiech if (flags & MLXBF_I2C_F_WRITE) { 739b5b5b320SKhalil Blaiech write_en = 1; 740b5b5b320SKhalil Blaiech write_len += operation->length; 741b5b5b320SKhalil Blaiech memcpy(data_desc + data_idx, 742b5b5b320SKhalil Blaiech operation->buffer, operation->length); 743b5b5b320SKhalil Blaiech data_idx += operation->length; 744b5b5b320SKhalil Blaiech } 745b5b5b320SKhalil Blaiech /* 746b5b5b320SKhalil Blaiech * We assume that read operations are performed only once per 747b5b5b320SKhalil Blaiech * SMBus transaction. *TBD* protect this statement so it won't 748b5b5b320SKhalil Blaiech * be executed twice? or return an error if we try to read more 749b5b5b320SKhalil Blaiech * than once? 750b5b5b320SKhalil Blaiech */ 751b5b5b320SKhalil Blaiech if (flags & MLXBF_I2C_F_READ) { 752b5b5b320SKhalil Blaiech read_en = 1; 753b5b5b320SKhalil Blaiech /* Subtract 1 as required by HW. */ 754b5b5b320SKhalil Blaiech read_len = operation->length - 1; 755b5b5b320SKhalil Blaiech read_buf = operation->buffer; 756b5b5b320SKhalil Blaiech } 757b5b5b320SKhalil Blaiech } 758b5b5b320SKhalil Blaiech 759b5b5b320SKhalil Blaiech /* Set Master GW data descriptor. */ 760b5b5b320SKhalil Blaiech data_len = write_len + 1; /* Add one byte of the slave address. */ 761b5b5b320SKhalil Blaiech /* 762b5b5b320SKhalil Blaiech * Note that data_len cannot be 0. Indeed, the slave address byte 763b5b5b320SKhalil Blaiech * must be written to the data registers. 764b5b5b320SKhalil Blaiech */ 765b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_write_data(priv, (const u8 *)data_desc, data_len, 766b5b5b320SKhalil Blaiech MLXBF_I2C_MASTER_DATA_DESC_ADDR); 767b5b5b320SKhalil Blaiech 768b5b5b320SKhalil Blaiech if (write_en) { 769b5b5b320SKhalil Blaiech ret = mlxbf_i2c_smbus_enable(priv, slave, write_len, block_en, 770b5b5b320SKhalil Blaiech pec_en, 0); 771b5b5b320SKhalil Blaiech if (ret) 772b5b5b320SKhalil Blaiech return ret; 773b5b5b320SKhalil Blaiech } 774b5b5b320SKhalil Blaiech 775b5b5b320SKhalil Blaiech if (read_en) { 776b5b5b320SKhalil Blaiech /* Write slave address to Master GW data descriptor. */ 777b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_write_data(priv, (const u8 *)&addr, 1, 778b5b5b320SKhalil Blaiech MLXBF_I2C_MASTER_DATA_DESC_ADDR); 779b5b5b320SKhalil Blaiech ret = mlxbf_i2c_smbus_enable(priv, slave, read_len, block_en, 780b5b5b320SKhalil Blaiech pec_en, 1); 781b5b5b320SKhalil Blaiech if (!ret) { 782b5b5b320SKhalil Blaiech /* Get Master GW data descriptor. */ 783b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_read_data(priv, data_desc, read_len + 1, 784b5b5b320SKhalil Blaiech MLXBF_I2C_MASTER_DATA_DESC_ADDR); 785b5b5b320SKhalil Blaiech 786b5b5b320SKhalil Blaiech /* Get data from Master GW data descriptor. */ 787b5b5b320SKhalil Blaiech memcpy(read_buf, data_desc, read_len + 1); 788b5b5b320SKhalil Blaiech } 789b5b5b320SKhalil Blaiech 790b5b5b320SKhalil Blaiech /* 791b5b5b320SKhalil Blaiech * After a read operation the SMBus FSM ps (present state) 792b5b5b320SKhalil Blaiech * needs to be 'manually' reset. This should be removed in 793b5b5b320SKhalil Blaiech * next tag integration. 794b5b5b320SKhalil Blaiech */ 7954b19d806SKhalil Blaiech writel(MLXBF_I2C_SMBUS_MASTER_FSM_PS_STATE_MASK, 7964b19d806SKhalil Blaiech priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_FSM); 797b5b5b320SKhalil Blaiech } 798b5b5b320SKhalil Blaiech 799b5b5b320SKhalil Blaiech return ret; 800b5b5b320SKhalil Blaiech } 801b5b5b320SKhalil Blaiech 802b5b5b320SKhalil Blaiech /* I2C SMBus protocols. */ 803b5b5b320SKhalil Blaiech 804b5b5b320SKhalil Blaiech static void 805b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_quick_command(struct mlxbf_i2c_smbus_request *request, 806b5b5b320SKhalil Blaiech u8 read) 807b5b5b320SKhalil Blaiech { 808b5b5b320SKhalil Blaiech request->operation_cnt = MLXBF_I2C_SMBUS_OP_CNT_1; 809b5b5b320SKhalil Blaiech 810b5b5b320SKhalil Blaiech request->operation[0].length = 0; 811b5b5b320SKhalil Blaiech request->operation[0].flags = MLXBF_I2C_F_WRITE; 812b5b5b320SKhalil Blaiech request->operation[0].flags |= read ? MLXBF_I2C_F_READ : 0; 813b5b5b320SKhalil Blaiech } 814b5b5b320SKhalil Blaiech 815b5b5b320SKhalil Blaiech static void mlxbf_i2c_smbus_byte_func(struct mlxbf_i2c_smbus_request *request, 816b5b5b320SKhalil Blaiech u8 *data, bool read, bool pec_check) 817b5b5b320SKhalil Blaiech { 818b5b5b320SKhalil Blaiech request->operation_cnt = MLXBF_I2C_SMBUS_OP_CNT_1; 819b5b5b320SKhalil Blaiech 820b5b5b320SKhalil Blaiech request->operation[0].length = 1; 821b5b5b320SKhalil Blaiech request->operation[0].length += pec_check; 822b5b5b320SKhalil Blaiech 823b5b5b320SKhalil Blaiech request->operation[0].flags = MLXBF_I2C_F_SMBUS_OPERATION; 824b5b5b320SKhalil Blaiech request->operation[0].flags |= read ? 825b5b5b320SKhalil Blaiech MLXBF_I2C_F_READ : MLXBF_I2C_F_WRITE; 826b5b5b320SKhalil Blaiech request->operation[0].flags |= pec_check ? MLXBF_I2C_F_SMBUS_PEC : 0; 827b5b5b320SKhalil Blaiech 828b5b5b320SKhalil Blaiech request->operation[0].buffer = data; 829b5b5b320SKhalil Blaiech } 830b5b5b320SKhalil Blaiech 831b5b5b320SKhalil Blaiech static void 832b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_data_byte_func(struct mlxbf_i2c_smbus_request *request, 833b5b5b320SKhalil Blaiech u8 *command, u8 *data, bool read, bool pec_check) 834b5b5b320SKhalil Blaiech { 835b5b5b320SKhalil Blaiech request->operation_cnt = MLXBF_I2C_SMBUS_OP_CNT_2; 836b5b5b320SKhalil Blaiech 837b5b5b320SKhalil Blaiech request->operation[0].length = 1; 838b5b5b320SKhalil Blaiech request->operation[0].flags = 839b5b5b320SKhalil Blaiech MLXBF_I2C_F_SMBUS_OPERATION | MLXBF_I2C_F_WRITE; 840b5b5b320SKhalil Blaiech request->operation[0].flags |= pec_check ? MLXBF_I2C_F_SMBUS_PEC : 0; 841b5b5b320SKhalil Blaiech request->operation[0].buffer = command; 842b5b5b320SKhalil Blaiech 843b5b5b320SKhalil Blaiech request->operation[1].length = 1; 844b5b5b320SKhalil Blaiech request->operation[1].length += pec_check; 845b5b5b320SKhalil Blaiech request->operation[1].flags = read ? 846b5b5b320SKhalil Blaiech MLXBF_I2C_F_READ : MLXBF_I2C_F_WRITE; 847b5b5b320SKhalil Blaiech request->operation[1].buffer = data; 848b5b5b320SKhalil Blaiech } 849b5b5b320SKhalil Blaiech 850b5b5b320SKhalil Blaiech static void 851b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_data_word_func(struct mlxbf_i2c_smbus_request *request, 852b5b5b320SKhalil Blaiech u8 *command, u8 *data, bool read, bool pec_check) 853b5b5b320SKhalil Blaiech { 854b5b5b320SKhalil Blaiech request->operation_cnt = MLXBF_I2C_SMBUS_OP_CNT_2; 855b5b5b320SKhalil Blaiech 856b5b5b320SKhalil Blaiech request->operation[0].length = 1; 857b5b5b320SKhalil Blaiech request->operation[0].flags = 858b5b5b320SKhalil Blaiech MLXBF_I2C_F_SMBUS_OPERATION | MLXBF_I2C_F_WRITE; 859b5b5b320SKhalil Blaiech request->operation[0].flags |= pec_check ? MLXBF_I2C_F_SMBUS_PEC : 0; 860b5b5b320SKhalil Blaiech request->operation[0].buffer = command; 861b5b5b320SKhalil Blaiech 862b5b5b320SKhalil Blaiech request->operation[1].length = 2; 863b5b5b320SKhalil Blaiech request->operation[1].length += pec_check; 864b5b5b320SKhalil Blaiech request->operation[1].flags = read ? 865b5b5b320SKhalil Blaiech MLXBF_I2C_F_READ : MLXBF_I2C_F_WRITE; 866b5b5b320SKhalil Blaiech request->operation[1].buffer = data; 867b5b5b320SKhalil Blaiech } 868b5b5b320SKhalil Blaiech 869b5b5b320SKhalil Blaiech static void 870b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_i2c_block_func(struct mlxbf_i2c_smbus_request *request, 871b5b5b320SKhalil Blaiech u8 *command, u8 *data, u8 *data_len, bool read, 872b5b5b320SKhalil Blaiech bool pec_check) 873b5b5b320SKhalil Blaiech { 874b5b5b320SKhalil Blaiech request->operation_cnt = MLXBF_I2C_SMBUS_OP_CNT_2; 875b5b5b320SKhalil Blaiech 876b5b5b320SKhalil Blaiech request->operation[0].length = 1; 877b5b5b320SKhalil Blaiech request->operation[0].flags = 878b5b5b320SKhalil Blaiech MLXBF_I2C_F_SMBUS_OPERATION | MLXBF_I2C_F_WRITE; 879b5b5b320SKhalil Blaiech request->operation[0].flags |= pec_check ? MLXBF_I2C_F_SMBUS_PEC : 0; 880b5b5b320SKhalil Blaiech request->operation[0].buffer = command; 881b5b5b320SKhalil Blaiech 882b5b5b320SKhalil Blaiech /* 883b5b5b320SKhalil Blaiech * As specified in the standard, the max number of bytes to read/write 884b5b5b320SKhalil Blaiech * per block operation is 32 bytes. In Golan code, the controller can 885b5b5b320SKhalil Blaiech * read up to 128 bytes and write up to 127 bytes. 886b5b5b320SKhalil Blaiech */ 887b5b5b320SKhalil Blaiech request->operation[1].length = 888b5b5b320SKhalil Blaiech (*data_len + pec_check > I2C_SMBUS_BLOCK_MAX) ? 889b5b5b320SKhalil Blaiech I2C_SMBUS_BLOCK_MAX : *data_len + pec_check; 890b5b5b320SKhalil Blaiech request->operation[1].flags = read ? 891b5b5b320SKhalil Blaiech MLXBF_I2C_F_READ : MLXBF_I2C_F_WRITE; 892b5b5b320SKhalil Blaiech /* 893b5b5b320SKhalil Blaiech * Skip the first data byte, which corresponds to the number of bytes 894b5b5b320SKhalil Blaiech * to read/write. 895b5b5b320SKhalil Blaiech */ 896b5b5b320SKhalil Blaiech request->operation[1].buffer = data + 1; 897b5b5b320SKhalil Blaiech 898b5b5b320SKhalil Blaiech *data_len = request->operation[1].length; 899b5b5b320SKhalil Blaiech 900b5b5b320SKhalil Blaiech /* Set the number of byte to read. This will be used by userspace. */ 901b5b5b320SKhalil Blaiech if (read) 902b5b5b320SKhalil Blaiech data[0] = *data_len; 903b5b5b320SKhalil Blaiech } 904b5b5b320SKhalil Blaiech 905b5b5b320SKhalil Blaiech static void mlxbf_i2c_smbus_block_func(struct mlxbf_i2c_smbus_request *request, 906b5b5b320SKhalil Blaiech u8 *command, u8 *data, u8 *data_len, 907b5b5b320SKhalil Blaiech bool read, bool pec_check) 908b5b5b320SKhalil Blaiech { 909b5b5b320SKhalil Blaiech request->operation_cnt = MLXBF_I2C_SMBUS_OP_CNT_2; 910b5b5b320SKhalil Blaiech 911b5b5b320SKhalil Blaiech request->operation[0].length = 1; 912b5b5b320SKhalil Blaiech request->operation[0].flags = 913b5b5b320SKhalil Blaiech MLXBF_I2C_F_SMBUS_OPERATION | MLXBF_I2C_F_WRITE; 914b5b5b320SKhalil Blaiech request->operation[0].flags |= MLXBF_I2C_F_SMBUS_BLOCK; 915b5b5b320SKhalil Blaiech request->operation[0].flags |= pec_check ? MLXBF_I2C_F_SMBUS_PEC : 0; 916b5b5b320SKhalil Blaiech request->operation[0].buffer = command; 917b5b5b320SKhalil Blaiech 918b5b5b320SKhalil Blaiech request->operation[1].length = 919b5b5b320SKhalil Blaiech (*data_len + pec_check > I2C_SMBUS_BLOCK_MAX) ? 920b5b5b320SKhalil Blaiech I2C_SMBUS_BLOCK_MAX : *data_len + pec_check; 921b5b5b320SKhalil Blaiech request->operation[1].flags = read ? 922b5b5b320SKhalil Blaiech MLXBF_I2C_F_READ : MLXBF_I2C_F_WRITE; 923b5b5b320SKhalil Blaiech request->operation[1].buffer = data + 1; 924b5b5b320SKhalil Blaiech 925b5b5b320SKhalil Blaiech *data_len = request->operation[1].length; 926b5b5b320SKhalil Blaiech 927b5b5b320SKhalil Blaiech /* Set the number of bytes to read. This will be used by userspace. */ 928b5b5b320SKhalil Blaiech if (read) 929b5b5b320SKhalil Blaiech data[0] = *data_len; 930b5b5b320SKhalil Blaiech } 931b5b5b320SKhalil Blaiech 932b5b5b320SKhalil Blaiech static void 933b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_process_call_func(struct mlxbf_i2c_smbus_request *request, 934b5b5b320SKhalil Blaiech u8 *command, u8 *data, bool pec_check) 935b5b5b320SKhalil Blaiech { 936b5b5b320SKhalil Blaiech request->operation_cnt = MLXBF_I2C_SMBUS_OP_CNT_3; 937b5b5b320SKhalil Blaiech 938b5b5b320SKhalil Blaiech request->operation[0].length = 1; 939b5b5b320SKhalil Blaiech request->operation[0].flags = 940b5b5b320SKhalil Blaiech MLXBF_I2C_F_SMBUS_OPERATION | MLXBF_I2C_F_WRITE; 941b5b5b320SKhalil Blaiech request->operation[0].flags |= MLXBF_I2C_F_SMBUS_BLOCK; 942b5b5b320SKhalil Blaiech request->operation[0].flags |= pec_check ? MLXBF_I2C_F_SMBUS_PEC : 0; 943b5b5b320SKhalil Blaiech request->operation[0].buffer = command; 944b5b5b320SKhalil Blaiech 945b5b5b320SKhalil Blaiech request->operation[1].length = 2; 946b5b5b320SKhalil Blaiech request->operation[1].flags = MLXBF_I2C_F_WRITE; 947b5b5b320SKhalil Blaiech request->operation[1].buffer = data; 948b5b5b320SKhalil Blaiech 949b5b5b320SKhalil Blaiech request->operation[2].length = 3; 950b5b5b320SKhalil Blaiech request->operation[2].flags = MLXBF_I2C_F_READ; 951b5b5b320SKhalil Blaiech request->operation[2].buffer = data; 952b5b5b320SKhalil Blaiech } 953b5b5b320SKhalil Blaiech 954b5b5b320SKhalil Blaiech static void 955b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_blk_process_call_func(struct mlxbf_i2c_smbus_request *request, 956b5b5b320SKhalil Blaiech u8 *command, u8 *data, u8 *data_len, 957b5b5b320SKhalil Blaiech bool pec_check) 958b5b5b320SKhalil Blaiech { 959b5b5b320SKhalil Blaiech u32 length; 960b5b5b320SKhalil Blaiech 961b5b5b320SKhalil Blaiech request->operation_cnt = MLXBF_I2C_SMBUS_OP_CNT_3; 962b5b5b320SKhalil Blaiech 963b5b5b320SKhalil Blaiech request->operation[0].length = 1; 964b5b5b320SKhalil Blaiech request->operation[0].flags = 965b5b5b320SKhalil Blaiech MLXBF_I2C_F_SMBUS_OPERATION | MLXBF_I2C_F_WRITE; 966b5b5b320SKhalil Blaiech request->operation[0].flags |= MLXBF_I2C_F_SMBUS_BLOCK; 967b5b5b320SKhalil Blaiech request->operation[0].flags |= (pec_check) ? MLXBF_I2C_F_SMBUS_PEC : 0; 968b5b5b320SKhalil Blaiech request->operation[0].buffer = command; 969b5b5b320SKhalil Blaiech 970b5b5b320SKhalil Blaiech length = (*data_len + pec_check > I2C_SMBUS_BLOCK_MAX) ? 971b5b5b320SKhalil Blaiech I2C_SMBUS_BLOCK_MAX : *data_len + pec_check; 972b5b5b320SKhalil Blaiech 973b5b5b320SKhalil Blaiech request->operation[1].length = length - pec_check; 974b5b5b320SKhalil Blaiech request->operation[1].flags = MLXBF_I2C_F_WRITE; 975b5b5b320SKhalil Blaiech request->operation[1].buffer = data; 976b5b5b320SKhalil Blaiech 977b5b5b320SKhalil Blaiech request->operation[2].length = length; 978b5b5b320SKhalil Blaiech request->operation[2].flags = MLXBF_I2C_F_READ; 979b5b5b320SKhalil Blaiech request->operation[2].buffer = data; 980b5b5b320SKhalil Blaiech 981b5b5b320SKhalil Blaiech *data_len = length; /* including PEC byte. */ 982b5b5b320SKhalil Blaiech } 983b5b5b320SKhalil Blaiech 984b5b5b320SKhalil Blaiech /* Initialization functions. */ 985b5b5b320SKhalil Blaiech 986b5b5b320SKhalil Blaiech static bool mlxbf_i2c_has_chip_type(struct mlxbf_i2c_priv *priv, u8 type) 987b5b5b320SKhalil Blaiech { 988b5b5b320SKhalil Blaiech return priv->chip->type == type; 989b5b5b320SKhalil Blaiech } 990b5b5b320SKhalil Blaiech 991b5b5b320SKhalil Blaiech static struct mlxbf_i2c_resource * 992b5b5b320SKhalil Blaiech mlxbf_i2c_get_shared_resource(struct mlxbf_i2c_priv *priv, u8 type) 993b5b5b320SKhalil Blaiech { 994b5b5b320SKhalil Blaiech const struct mlxbf_i2c_chip_info *chip = priv->chip; 995b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *res; 996b5b5b320SKhalil Blaiech u8 res_idx = 0; 997b5b5b320SKhalil Blaiech 998b5b5b320SKhalil Blaiech for (res_idx = 0; res_idx < MLXBF_I2C_SHARED_RES_MAX; res_idx++) { 999b5b5b320SKhalil Blaiech res = chip->shared_res[res_idx]; 1000b5b5b320SKhalil Blaiech if (res && res->type == type) 1001b5b5b320SKhalil Blaiech return res; 1002b5b5b320SKhalil Blaiech } 1003b5b5b320SKhalil Blaiech 1004b5b5b320SKhalil Blaiech return NULL; 1005b5b5b320SKhalil Blaiech } 1006b5b5b320SKhalil Blaiech 1007b5b5b320SKhalil Blaiech static int mlxbf_i2c_init_resource(struct platform_device *pdev, 1008b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource **res, 1009b5b5b320SKhalil Blaiech u8 type) 1010b5b5b320SKhalil Blaiech { 1011b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *tmp_res; 1012b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 1013b5b5b320SKhalil Blaiech 1014b5b5b320SKhalil Blaiech if (!res || *res || type >= MLXBF_I2C_END_RES) 1015b5b5b320SKhalil Blaiech return -EINVAL; 1016b5b5b320SKhalil Blaiech 1017b5b5b320SKhalil Blaiech tmp_res = devm_kzalloc(dev, sizeof(struct mlxbf_i2c_resource), 1018b5b5b320SKhalil Blaiech GFP_KERNEL); 1019b5b5b320SKhalil Blaiech if (!tmp_res) 1020b5b5b320SKhalil Blaiech return -ENOMEM; 1021b5b5b320SKhalil Blaiech 1022b5b5b320SKhalil Blaiech tmp_res->params = platform_get_resource(pdev, IORESOURCE_MEM, type); 1023b5b5b320SKhalil Blaiech if (!tmp_res->params) { 1024b5b5b320SKhalil Blaiech devm_kfree(dev, tmp_res); 1025b5b5b320SKhalil Blaiech return -EIO; 1026b5b5b320SKhalil Blaiech } 1027b5b5b320SKhalil Blaiech 1028b5b5b320SKhalil Blaiech tmp_res->io = devm_ioremap_resource(dev, tmp_res->params); 1029b5b5b320SKhalil Blaiech if (IS_ERR(tmp_res->io)) { 1030b5b5b320SKhalil Blaiech devm_kfree(dev, tmp_res); 1031b5b5b320SKhalil Blaiech return PTR_ERR(tmp_res->io); 1032b5b5b320SKhalil Blaiech } 1033b5b5b320SKhalil Blaiech 1034b5b5b320SKhalil Blaiech tmp_res->type = type; 1035b5b5b320SKhalil Blaiech 1036b5b5b320SKhalil Blaiech *res = tmp_res; 1037b5b5b320SKhalil Blaiech 1038b5b5b320SKhalil Blaiech return 0; 1039b5b5b320SKhalil Blaiech } 1040b5b5b320SKhalil Blaiech 1041b5b5b320SKhalil Blaiech static u32 mlxbf_i2c_get_ticks(struct mlxbf_i2c_priv *priv, u64 nanoseconds, 1042b5b5b320SKhalil Blaiech bool minimum) 1043b5b5b320SKhalil Blaiech { 1044b5b5b320SKhalil Blaiech u64 frequency; 1045b5b5b320SKhalil Blaiech u32 ticks; 1046b5b5b320SKhalil Blaiech 1047b5b5b320SKhalil Blaiech /* 1048b5b5b320SKhalil Blaiech * Compute ticks as follow: 1049b5b5b320SKhalil Blaiech * 1050b5b5b320SKhalil Blaiech * Ticks 1051b5b5b320SKhalil Blaiech * Time = --------- x 10^9 => Ticks = Time x Frequency x 10^-9 1052b5b5b320SKhalil Blaiech * Frequency 1053b5b5b320SKhalil Blaiech */ 1054b5b5b320SKhalil Blaiech frequency = priv->frequency; 1055b5b5b320SKhalil Blaiech ticks = (nanoseconds * frequency) / MLXBF_I2C_FREQUENCY_1GHZ; 1056b5b5b320SKhalil Blaiech /* 1057b5b5b320SKhalil Blaiech * The number of ticks is rounded down and if minimum is equal to 1 1058b5b5b320SKhalil Blaiech * then add one tick. 1059b5b5b320SKhalil Blaiech */ 1060b5b5b320SKhalil Blaiech if (minimum) 1061b5b5b320SKhalil Blaiech ticks++; 1062b5b5b320SKhalil Blaiech 1063b5b5b320SKhalil Blaiech return ticks; 1064b5b5b320SKhalil Blaiech } 1065b5b5b320SKhalil Blaiech 1066b5b5b320SKhalil Blaiech static u32 mlxbf_i2c_set_timer(struct mlxbf_i2c_priv *priv, u64 nsec, bool opt, 1067b5b5b320SKhalil Blaiech u32 mask, u8 shift) 1068b5b5b320SKhalil Blaiech { 1069b5b5b320SKhalil Blaiech u32 val = (mlxbf_i2c_get_ticks(priv, nsec, opt) & mask) << shift; 1070b5b5b320SKhalil Blaiech 1071b5b5b320SKhalil Blaiech return val; 1072b5b5b320SKhalil Blaiech } 1073b5b5b320SKhalil Blaiech 1074b5b5b320SKhalil Blaiech static void mlxbf_i2c_set_timings(struct mlxbf_i2c_priv *priv, 1075b5b5b320SKhalil Blaiech const struct mlxbf_i2c_timings *timings) 1076b5b5b320SKhalil Blaiech { 1077b5b5b320SKhalil Blaiech u32 timer; 1078b5b5b320SKhalil Blaiech 1079b5b5b320SKhalil Blaiech timer = mlxbf_i2c_set_timer(priv, timings->scl_high, 1080b5b5b320SKhalil Blaiech false, MLXBF_I2C_MASK_16, 1081b5b5b320SKhalil Blaiech MLXBF_I2C_SHIFT_0); 1082b5b5b320SKhalil Blaiech timer |= mlxbf_i2c_set_timer(priv, timings->scl_low, 1083b5b5b320SKhalil Blaiech false, MLXBF_I2C_MASK_16, 1084b5b5b320SKhalil Blaiech MLXBF_I2C_SHIFT_16); 10854b19d806SKhalil Blaiech writel(timer, priv->smbus->io + 10864b19d806SKhalil Blaiech MLXBF_I2C_SMBUS_TIMER_SCL_LOW_SCL_HIGH); 1087b5b5b320SKhalil Blaiech 1088b5b5b320SKhalil Blaiech timer = mlxbf_i2c_set_timer(priv, timings->sda_rise, false, 1089b5b5b320SKhalil Blaiech MLXBF_I2C_MASK_8, MLXBF_I2C_SHIFT_0); 1090b5b5b320SKhalil Blaiech timer |= mlxbf_i2c_set_timer(priv, timings->sda_fall, false, 1091b5b5b320SKhalil Blaiech MLXBF_I2C_MASK_8, MLXBF_I2C_SHIFT_8); 1092b5b5b320SKhalil Blaiech timer |= mlxbf_i2c_set_timer(priv, timings->scl_rise, false, 1093b5b5b320SKhalil Blaiech MLXBF_I2C_MASK_8, MLXBF_I2C_SHIFT_16); 1094b5b5b320SKhalil Blaiech timer |= mlxbf_i2c_set_timer(priv, timings->scl_fall, false, 1095b5b5b320SKhalil Blaiech MLXBF_I2C_MASK_8, MLXBF_I2C_SHIFT_24); 10964b19d806SKhalil Blaiech writel(timer, priv->smbus->io + 10974b19d806SKhalil Blaiech MLXBF_I2C_SMBUS_TIMER_FALL_RISE_SPIKE); 1098b5b5b320SKhalil Blaiech 1099b5b5b320SKhalil Blaiech timer = mlxbf_i2c_set_timer(priv, timings->hold_start, true, 1100b5b5b320SKhalil Blaiech MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_0); 1101b5b5b320SKhalil Blaiech timer |= mlxbf_i2c_set_timer(priv, timings->hold_data, true, 1102b5b5b320SKhalil Blaiech MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_16); 11034b19d806SKhalil Blaiech writel(timer, priv->smbus->io + MLXBF_I2C_SMBUS_TIMER_THOLD); 1104b5b5b320SKhalil Blaiech 1105b5b5b320SKhalil Blaiech timer = mlxbf_i2c_set_timer(priv, timings->setup_start, true, 1106b5b5b320SKhalil Blaiech MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_0); 1107b5b5b320SKhalil Blaiech timer |= mlxbf_i2c_set_timer(priv, timings->setup_stop, true, 1108b5b5b320SKhalil Blaiech MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_16); 11094b19d806SKhalil Blaiech writel(timer, priv->smbus->io + 11104b19d806SKhalil Blaiech MLXBF_I2C_SMBUS_TIMER_TSETUP_START_STOP); 1111b5b5b320SKhalil Blaiech 1112b5b5b320SKhalil Blaiech timer = mlxbf_i2c_set_timer(priv, timings->setup_data, true, 1113b5b5b320SKhalil Blaiech MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_0); 11144b19d806SKhalil Blaiech writel(timer, priv->smbus->io + MLXBF_I2C_SMBUS_TIMER_TSETUP_DATA); 1115b5b5b320SKhalil Blaiech 1116b5b5b320SKhalil Blaiech timer = mlxbf_i2c_set_timer(priv, timings->buf, false, 1117b5b5b320SKhalil Blaiech MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_0); 1118b5b5b320SKhalil Blaiech timer |= mlxbf_i2c_set_timer(priv, timings->thigh_max, false, 1119b5b5b320SKhalil Blaiech MLXBF_I2C_MASK_16, MLXBF_I2C_SHIFT_16); 11204b19d806SKhalil Blaiech writel(timer, priv->smbus->io + MLXBF_I2C_SMBUS_THIGH_MAX_TBUF); 1121b5b5b320SKhalil Blaiech 1122b5b5b320SKhalil Blaiech timer = timings->timeout; 11234b19d806SKhalil Blaiech writel(timer, priv->smbus->io + MLXBF_I2C_SMBUS_SCL_LOW_TIMEOUT); 1124b5b5b320SKhalil Blaiech } 1125b5b5b320SKhalil Blaiech 1126b5b5b320SKhalil Blaiech enum mlxbf_i2c_timings_config { 1127b5b5b320SKhalil Blaiech MLXBF_I2C_TIMING_CONFIG_100KHZ, 1128b5b5b320SKhalil Blaiech MLXBF_I2C_TIMING_CONFIG_400KHZ, 1129b5b5b320SKhalil Blaiech MLXBF_I2C_TIMING_CONFIG_1000KHZ, 1130b5b5b320SKhalil Blaiech }; 1131b5b5b320SKhalil Blaiech 1132b5b5b320SKhalil Blaiech /* 1133b5b5b320SKhalil Blaiech * Note that the mlxbf_i2c_timings->timeout value is not related to the 1134b5b5b320SKhalil Blaiech * bus frequency, it is impacted by the time it takes the driver to 1135b5b5b320SKhalil Blaiech * complete data transmission before transaction abort. 1136b5b5b320SKhalil Blaiech */ 1137b5b5b320SKhalil Blaiech static const struct mlxbf_i2c_timings mlxbf_i2c_timings[] = { 1138b5b5b320SKhalil Blaiech [MLXBF_I2C_TIMING_CONFIG_100KHZ] = { 1139b5b5b320SKhalil Blaiech .scl_high = 4810, 1140b5b5b320SKhalil Blaiech .scl_low = 5000, 1141b5b5b320SKhalil Blaiech .hold_start = 4000, 1142b5b5b320SKhalil Blaiech .setup_start = 4800, 1143b5b5b320SKhalil Blaiech .setup_stop = 4000, 1144b5b5b320SKhalil Blaiech .setup_data = 250, 1145b5b5b320SKhalil Blaiech .sda_rise = 50, 1146b5b5b320SKhalil Blaiech .sda_fall = 50, 1147b5b5b320SKhalil Blaiech .scl_rise = 50, 1148b5b5b320SKhalil Blaiech .scl_fall = 50, 1149b5b5b320SKhalil Blaiech .hold_data = 300, 1150b5b5b320SKhalil Blaiech .buf = 20000, 1151b5b5b320SKhalil Blaiech .thigh_max = 5000, 1152b5b5b320SKhalil Blaiech .timeout = 106500 1153b5b5b320SKhalil Blaiech }, 1154b5b5b320SKhalil Blaiech [MLXBF_I2C_TIMING_CONFIG_400KHZ] = { 1155b5b5b320SKhalil Blaiech .scl_high = 1011, 1156b5b5b320SKhalil Blaiech .scl_low = 1300, 1157b5b5b320SKhalil Blaiech .hold_start = 600, 1158b5b5b320SKhalil Blaiech .setup_start = 700, 1159b5b5b320SKhalil Blaiech .setup_stop = 600, 1160b5b5b320SKhalil Blaiech .setup_data = 100, 1161b5b5b320SKhalil Blaiech .sda_rise = 50, 1162b5b5b320SKhalil Blaiech .sda_fall = 50, 1163b5b5b320SKhalil Blaiech .scl_rise = 50, 1164b5b5b320SKhalil Blaiech .scl_fall = 50, 1165b5b5b320SKhalil Blaiech .hold_data = 300, 1166b5b5b320SKhalil Blaiech .buf = 20000, 1167b5b5b320SKhalil Blaiech .thigh_max = 5000, 1168b5b5b320SKhalil Blaiech .timeout = 106500 1169b5b5b320SKhalil Blaiech }, 1170b5b5b320SKhalil Blaiech [MLXBF_I2C_TIMING_CONFIG_1000KHZ] = { 1171b5b5b320SKhalil Blaiech .scl_high = 600, 1172b5b5b320SKhalil Blaiech .scl_low = 1300, 1173b5b5b320SKhalil Blaiech .hold_start = 600, 1174b5b5b320SKhalil Blaiech .setup_start = 600, 1175b5b5b320SKhalil Blaiech .setup_stop = 600, 1176b5b5b320SKhalil Blaiech .setup_data = 100, 1177b5b5b320SKhalil Blaiech .sda_rise = 50, 1178b5b5b320SKhalil Blaiech .sda_fall = 50, 1179b5b5b320SKhalil Blaiech .scl_rise = 50, 1180b5b5b320SKhalil Blaiech .scl_fall = 50, 1181b5b5b320SKhalil Blaiech .hold_data = 300, 1182b5b5b320SKhalil Blaiech .buf = 20000, 1183b5b5b320SKhalil Blaiech .thigh_max = 5000, 1184b5b5b320SKhalil Blaiech .timeout = 106500 1185b5b5b320SKhalil Blaiech } 1186b5b5b320SKhalil Blaiech }; 1187b5b5b320SKhalil Blaiech 1188b5b5b320SKhalil Blaiech static int mlxbf_i2c_init_timings(struct platform_device *pdev, 1189b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv) 1190b5b5b320SKhalil Blaiech { 1191b5b5b320SKhalil Blaiech enum mlxbf_i2c_timings_config config_idx; 1192b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 1193b5b5b320SKhalil Blaiech u32 config_khz; 1194b5b5b320SKhalil Blaiech 1195b5b5b320SKhalil Blaiech int ret; 1196b5b5b320SKhalil Blaiech 1197b5b5b320SKhalil Blaiech ret = device_property_read_u32(dev, "clock-frequency", &config_khz); 1198b5b5b320SKhalil Blaiech if (ret < 0) 1199fd6ddaa0SAndy Shevchenko config_khz = I2C_MAX_STANDARD_MODE_FREQ; 1200b5b5b320SKhalil Blaiech 1201b5b5b320SKhalil Blaiech switch (config_khz) { 1202b5b5b320SKhalil Blaiech default: 1203b5b5b320SKhalil Blaiech /* Default settings is 100 KHz. */ 1204b5b5b320SKhalil Blaiech pr_warn("Illegal value %d: defaulting to 100 KHz\n", 1205b5b5b320SKhalil Blaiech config_khz); 1206b5b5b320SKhalil Blaiech fallthrough; 1207fd6ddaa0SAndy Shevchenko case I2C_MAX_STANDARD_MODE_FREQ: 1208b5b5b320SKhalil Blaiech config_idx = MLXBF_I2C_TIMING_CONFIG_100KHZ; 1209b5b5b320SKhalil Blaiech break; 1210b5b5b320SKhalil Blaiech 1211fd6ddaa0SAndy Shevchenko case I2C_MAX_FAST_MODE_FREQ: 1212b5b5b320SKhalil Blaiech config_idx = MLXBF_I2C_TIMING_CONFIG_400KHZ; 1213b5b5b320SKhalil Blaiech break; 1214b5b5b320SKhalil Blaiech 1215fd6ddaa0SAndy Shevchenko case I2C_MAX_FAST_MODE_PLUS_FREQ: 1216b5b5b320SKhalil Blaiech config_idx = MLXBF_I2C_TIMING_CONFIG_1000KHZ; 1217b5b5b320SKhalil Blaiech break; 1218b5b5b320SKhalil Blaiech } 1219b5b5b320SKhalil Blaiech 1220b5b5b320SKhalil Blaiech mlxbf_i2c_set_timings(priv, &mlxbf_i2c_timings[config_idx]); 1221b5b5b320SKhalil Blaiech 1222b5b5b320SKhalil Blaiech return 0; 1223b5b5b320SKhalil Blaiech } 1224b5b5b320SKhalil Blaiech 1225b5b5b320SKhalil Blaiech static int mlxbf_i2c_get_gpio(struct platform_device *pdev, 1226b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv) 1227b5b5b320SKhalil Blaiech { 1228b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *gpio_res; 1229b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 1230b5b5b320SKhalil Blaiech struct resource *params; 1231b5b5b320SKhalil Blaiech resource_size_t size; 1232b5b5b320SKhalil Blaiech 1233b5b5b320SKhalil Blaiech gpio_res = mlxbf_i2c_get_shared_resource(priv, MLXBF_I2C_GPIO_RES); 1234b5b5b320SKhalil Blaiech if (!gpio_res) 1235b5b5b320SKhalil Blaiech return -EPERM; 1236b5b5b320SKhalil Blaiech 1237b5b5b320SKhalil Blaiech /* 1238b5b5b320SKhalil Blaiech * The GPIO region in TYU space is shared among I2C busses. 1239b5b5b320SKhalil Blaiech * This function MUST be serialized to avoid racing when 1240b5b5b320SKhalil Blaiech * claiming the memory region and/or setting up the GPIO. 1241b5b5b320SKhalil Blaiech */ 1242b5b5b320SKhalil Blaiech lockdep_assert_held(gpio_res->lock); 1243b5b5b320SKhalil Blaiech 1244b5b5b320SKhalil Blaiech /* Check whether the memory map exist. */ 1245b5b5b320SKhalil Blaiech if (gpio_res->io) 1246b5b5b320SKhalil Blaiech return 0; 1247b5b5b320SKhalil Blaiech 1248b5b5b320SKhalil Blaiech params = gpio_res->params; 1249b5b5b320SKhalil Blaiech size = resource_size(params); 1250b5b5b320SKhalil Blaiech 1251b5b5b320SKhalil Blaiech if (!devm_request_mem_region(dev, params->start, size, params->name)) 1252b5b5b320SKhalil Blaiech return -EFAULT; 1253b5b5b320SKhalil Blaiech 1254b5b5b320SKhalil Blaiech gpio_res->io = devm_ioremap(dev, params->start, size); 12552bf95456SWang Xiaojun if (!gpio_res->io) { 1256b5b5b320SKhalil Blaiech devm_release_mem_region(dev, params->start, size); 12572bf95456SWang Xiaojun return -ENOMEM; 1258b5b5b320SKhalil Blaiech } 1259b5b5b320SKhalil Blaiech 1260b5b5b320SKhalil Blaiech return 0; 1261b5b5b320SKhalil Blaiech } 1262b5b5b320SKhalil Blaiech 1263b5b5b320SKhalil Blaiech static int mlxbf_i2c_release_gpio(struct platform_device *pdev, 1264b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv) 1265b5b5b320SKhalil Blaiech { 1266b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *gpio_res; 1267b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 1268b5b5b320SKhalil Blaiech struct resource *params; 1269b5b5b320SKhalil Blaiech 1270b5b5b320SKhalil Blaiech gpio_res = mlxbf_i2c_get_shared_resource(priv, MLXBF_I2C_GPIO_RES); 1271b5b5b320SKhalil Blaiech if (!gpio_res) 1272b5b5b320SKhalil Blaiech return 0; 1273b5b5b320SKhalil Blaiech 1274b5b5b320SKhalil Blaiech mutex_lock(gpio_res->lock); 1275b5b5b320SKhalil Blaiech 1276b5b5b320SKhalil Blaiech if (gpio_res->io) { 1277b5b5b320SKhalil Blaiech /* Release the GPIO resource. */ 1278b5b5b320SKhalil Blaiech params = gpio_res->params; 1279b5b5b320SKhalil Blaiech devm_iounmap(dev, gpio_res->io); 1280b5b5b320SKhalil Blaiech devm_release_mem_region(dev, params->start, 1281b5b5b320SKhalil Blaiech resource_size(params)); 1282b5b5b320SKhalil Blaiech } 1283b5b5b320SKhalil Blaiech 1284b5b5b320SKhalil Blaiech mutex_unlock(gpio_res->lock); 1285b5b5b320SKhalil Blaiech 1286b5b5b320SKhalil Blaiech return 0; 1287b5b5b320SKhalil Blaiech } 1288b5b5b320SKhalil Blaiech 1289b5b5b320SKhalil Blaiech static int mlxbf_i2c_get_corepll(struct platform_device *pdev, 1290b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv) 1291b5b5b320SKhalil Blaiech { 1292b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *corepll_res; 1293b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 1294b5b5b320SKhalil Blaiech struct resource *params; 1295b5b5b320SKhalil Blaiech resource_size_t size; 1296b5b5b320SKhalil Blaiech 1297b5b5b320SKhalil Blaiech corepll_res = mlxbf_i2c_get_shared_resource(priv, 1298b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_RES); 1299b5b5b320SKhalil Blaiech if (!corepll_res) 1300b5b5b320SKhalil Blaiech return -EPERM; 1301b5b5b320SKhalil Blaiech 1302b5b5b320SKhalil Blaiech /* 1303b5b5b320SKhalil Blaiech * The COREPLL region in TYU space is shared among I2C busses. 1304b5b5b320SKhalil Blaiech * This function MUST be serialized to avoid racing when 1305b5b5b320SKhalil Blaiech * claiming the memory region. 1306b5b5b320SKhalil Blaiech */ 1307b5b5b320SKhalil Blaiech lockdep_assert_held(corepll_res->lock); 1308b5b5b320SKhalil Blaiech 1309b5b5b320SKhalil Blaiech /* Check whether the memory map exist. */ 1310b5b5b320SKhalil Blaiech if (corepll_res->io) 1311b5b5b320SKhalil Blaiech return 0; 1312b5b5b320SKhalil Blaiech 1313b5b5b320SKhalil Blaiech params = corepll_res->params; 1314b5b5b320SKhalil Blaiech size = resource_size(params); 1315b5b5b320SKhalil Blaiech 1316b5b5b320SKhalil Blaiech if (!devm_request_mem_region(dev, params->start, size, params->name)) 1317b5b5b320SKhalil Blaiech return -EFAULT; 1318b5b5b320SKhalil Blaiech 1319b5b5b320SKhalil Blaiech corepll_res->io = devm_ioremap(dev, params->start, size); 13202bf95456SWang Xiaojun if (!corepll_res->io) { 1321b5b5b320SKhalil Blaiech devm_release_mem_region(dev, params->start, size); 13222bf95456SWang Xiaojun return -ENOMEM; 1323b5b5b320SKhalil Blaiech } 1324b5b5b320SKhalil Blaiech 1325b5b5b320SKhalil Blaiech return 0; 1326b5b5b320SKhalil Blaiech } 1327b5b5b320SKhalil Blaiech 1328b5b5b320SKhalil Blaiech static int mlxbf_i2c_release_corepll(struct platform_device *pdev, 1329b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv) 1330b5b5b320SKhalil Blaiech { 1331b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *corepll_res; 1332b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 1333b5b5b320SKhalil Blaiech struct resource *params; 1334b5b5b320SKhalil Blaiech 1335b5b5b320SKhalil Blaiech corepll_res = mlxbf_i2c_get_shared_resource(priv, 1336b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_RES); 1337b5b5b320SKhalil Blaiech 1338b5b5b320SKhalil Blaiech mutex_lock(corepll_res->lock); 1339b5b5b320SKhalil Blaiech 1340b5b5b320SKhalil Blaiech if (corepll_res->io) { 1341b5b5b320SKhalil Blaiech /* Release the CorePLL resource. */ 1342b5b5b320SKhalil Blaiech params = corepll_res->params; 1343b5b5b320SKhalil Blaiech devm_iounmap(dev, corepll_res->io); 1344b5b5b320SKhalil Blaiech devm_release_mem_region(dev, params->start, 1345b5b5b320SKhalil Blaiech resource_size(params)); 1346b5b5b320SKhalil Blaiech } 1347b5b5b320SKhalil Blaiech 1348b5b5b320SKhalil Blaiech mutex_unlock(corepll_res->lock); 1349b5b5b320SKhalil Blaiech 1350b5b5b320SKhalil Blaiech return 0; 1351b5b5b320SKhalil Blaiech } 1352b5b5b320SKhalil Blaiech 1353b5b5b320SKhalil Blaiech static int mlxbf_i2c_init_master(struct platform_device *pdev, 1354b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv) 1355b5b5b320SKhalil Blaiech { 1356b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *gpio_res; 1357b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 1358b5b5b320SKhalil Blaiech u32 config_reg; 1359b5b5b320SKhalil Blaiech int ret; 1360b5b5b320SKhalil Blaiech 1361b5b5b320SKhalil Blaiech /* This configuration is only needed for BlueField 1. */ 1362b5b5b320SKhalil Blaiech if (!mlxbf_i2c_has_chip_type(priv, MLXBF_I2C_CHIP_TYPE_1)) 1363b5b5b320SKhalil Blaiech return 0; 1364b5b5b320SKhalil Blaiech 1365b5b5b320SKhalil Blaiech gpio_res = mlxbf_i2c_get_shared_resource(priv, MLXBF_I2C_GPIO_RES); 1366b5b5b320SKhalil Blaiech if (!gpio_res) 1367b5b5b320SKhalil Blaiech return -EPERM; 1368b5b5b320SKhalil Blaiech 1369b5b5b320SKhalil Blaiech /* 1370b5b5b320SKhalil Blaiech * The GPIO region in TYU space is shared among I2C busses. 1371b5b5b320SKhalil Blaiech * This function MUST be serialized to avoid racing when 1372b5b5b320SKhalil Blaiech * claiming the memory region and/or setting up the GPIO. 1373b5b5b320SKhalil Blaiech */ 1374b5b5b320SKhalil Blaiech 1375b5b5b320SKhalil Blaiech mutex_lock(gpio_res->lock); 1376b5b5b320SKhalil Blaiech 1377b5b5b320SKhalil Blaiech ret = mlxbf_i2c_get_gpio(pdev, priv); 1378b5b5b320SKhalil Blaiech if (ret < 0) { 1379b5b5b320SKhalil Blaiech dev_err(dev, "Failed to get gpio resource"); 1380b5b5b320SKhalil Blaiech mutex_unlock(gpio_res->lock); 1381b5b5b320SKhalil Blaiech return ret; 1382b5b5b320SKhalil Blaiech } 1383b5b5b320SKhalil Blaiech 1384b5b5b320SKhalil Blaiech /* 1385b5b5b320SKhalil Blaiech * TYU - Configuration for GPIO pins. Those pins must be asserted in 1386b5b5b320SKhalil Blaiech * MLXBF_I2C_GPIO_0_FUNC_EN_0, i.e. GPIO 0 is controlled by HW, and must 1387b5b5b320SKhalil Blaiech * be reset in MLXBF_I2C_GPIO_0_FORCE_OE_EN, i.e. GPIO_OE will be driven 1388b5b5b320SKhalil Blaiech * instead of HW_OE. 1389b5b5b320SKhalil Blaiech * For now, we do not reset the GPIO state when the driver is removed. 1390b5b5b320SKhalil Blaiech * First, it is not necessary to disable the bus since we are using 1391b5b5b320SKhalil Blaiech * the same busses. Then, some busses might be shared among Linux and 1392b5b5b320SKhalil Blaiech * platform firmware; disabling the bus might compromise the system 1393b5b5b320SKhalil Blaiech * functionality. 1394b5b5b320SKhalil Blaiech */ 13954b19d806SKhalil Blaiech config_reg = readl(gpio_res->io + MLXBF_I2C_GPIO_0_FUNC_EN_0); 1396b5b5b320SKhalil Blaiech config_reg = MLXBF_I2C_GPIO_SMBUS_GW_ASSERT_PINS(priv->bus, 1397b5b5b320SKhalil Blaiech config_reg); 13984b19d806SKhalil Blaiech writel(config_reg, gpio_res->io + MLXBF_I2C_GPIO_0_FUNC_EN_0); 1399b5b5b320SKhalil Blaiech 14004b19d806SKhalil Blaiech config_reg = readl(gpio_res->io + MLXBF_I2C_GPIO_0_FORCE_OE_EN); 1401b5b5b320SKhalil Blaiech config_reg = MLXBF_I2C_GPIO_SMBUS_GW_RESET_PINS(priv->bus, 1402b5b5b320SKhalil Blaiech config_reg); 14034b19d806SKhalil Blaiech writel(config_reg, gpio_res->io + MLXBF_I2C_GPIO_0_FORCE_OE_EN); 1404b5b5b320SKhalil Blaiech 1405b5b5b320SKhalil Blaiech mutex_unlock(gpio_res->lock); 1406b5b5b320SKhalil Blaiech 1407b5b5b320SKhalil Blaiech return 0; 1408b5b5b320SKhalil Blaiech } 1409b5b5b320SKhalil Blaiech 1410b5b5b320SKhalil Blaiech static u64 mlxbf_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res) 1411b5b5b320SKhalil Blaiech { 1412b5b5b320SKhalil Blaiech u64 core_frequency, pad_frequency; 1413b5b5b320SKhalil Blaiech u8 core_od, core_r; 1414b5b5b320SKhalil Blaiech u32 corepll_val; 1415b5b5b320SKhalil Blaiech u16 core_f; 1416b5b5b320SKhalil Blaiech 141767ee9fdaSKhalil Blaiech pad_frequency = MLXBF_I2C_PLL_IN_FREQ; 1418b5b5b320SKhalil Blaiech 14194b19d806SKhalil Blaiech corepll_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1); 1420b5b5b320SKhalil Blaiech 1421b5b5b320SKhalil Blaiech /* Get Core PLL configuration bits. */ 1422b5b5b320SKhalil Blaiech core_f = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT) & 1423b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_CORE_F_TYU_MASK; 1424b5b5b320SKhalil Blaiech core_od = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT) & 1425b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK; 1426b5b5b320SKhalil Blaiech core_r = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT) & 1427b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_CORE_R_TYU_MASK; 1428b5b5b320SKhalil Blaiech 1429b5b5b320SKhalil Blaiech /* 1430b5b5b320SKhalil Blaiech * Compute PLL output frequency as follow: 1431b5b5b320SKhalil Blaiech * 1432b5b5b320SKhalil Blaiech * CORE_F + 1 1433b5b5b320SKhalil Blaiech * PLL_OUT_FREQ = PLL_IN_FREQ * ---------------------------- 1434b5b5b320SKhalil Blaiech * (CORE_R + 1) * (CORE_OD + 1) 1435b5b5b320SKhalil Blaiech * 1436b5b5b320SKhalil Blaiech * Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency 1437b5b5b320SKhalil Blaiech * and PadFrequency, respectively. 1438b5b5b320SKhalil Blaiech */ 1439b5b5b320SKhalil Blaiech core_frequency = pad_frequency * (++core_f); 1440b5b5b320SKhalil Blaiech core_frequency /= (++core_r) * (++core_od); 1441b5b5b320SKhalil Blaiech 1442b5b5b320SKhalil Blaiech return core_frequency; 1443b5b5b320SKhalil Blaiech } 1444b5b5b320SKhalil Blaiech 1445b5b5b320SKhalil Blaiech static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res) 1446b5b5b320SKhalil Blaiech { 1447b5b5b320SKhalil Blaiech u32 corepll_reg1_val, corepll_reg2_val; 1448b5b5b320SKhalil Blaiech u64 corepll_frequency, pad_frequency; 1449b5b5b320SKhalil Blaiech u8 core_od, core_r; 1450b5b5b320SKhalil Blaiech u32 core_f; 1451b5b5b320SKhalil Blaiech 145267ee9fdaSKhalil Blaiech pad_frequency = MLXBF_I2C_PLL_IN_FREQ; 1453b5b5b320SKhalil Blaiech 14544b19d806SKhalil Blaiech corepll_reg1_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1); 14554b19d806SKhalil Blaiech corepll_reg2_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG2); 1456b5b5b320SKhalil Blaiech 1457b5b5b320SKhalil Blaiech /* Get Core PLL configuration bits */ 1458b5b5b320SKhalil Blaiech core_f = rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT) & 1459b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_CORE_F_YU_MASK; 1460b5b5b320SKhalil Blaiech core_r = rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT) & 1461b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_CORE_R_YU_MASK; 1462b5b5b320SKhalil Blaiech core_od = rol32(corepll_reg2_val, MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT) & 1463b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_CORE_OD_YU_MASK; 1464b5b5b320SKhalil Blaiech 1465b5b5b320SKhalil Blaiech /* 1466b5b5b320SKhalil Blaiech * Compute PLL output frequency as follow: 1467b5b5b320SKhalil Blaiech * 1468b5b5b320SKhalil Blaiech * CORE_F / 16384 1469b5b5b320SKhalil Blaiech * PLL_OUT_FREQ = PLL_IN_FREQ * ---------------------------- 1470b5b5b320SKhalil Blaiech * (CORE_R + 1) * (CORE_OD + 1) 1471b5b5b320SKhalil Blaiech * 1472b5b5b320SKhalil Blaiech * Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency 1473b5b5b320SKhalil Blaiech * and PadFrequency, respectively. 1474b5b5b320SKhalil Blaiech */ 1475b5b5b320SKhalil Blaiech corepll_frequency = (pad_frequency * core_f) / MLNXBF_I2C_COREPLL_CONST; 1476b5b5b320SKhalil Blaiech corepll_frequency /= (++core_r) * (++core_od); 1477b5b5b320SKhalil Blaiech 1478b5b5b320SKhalil Blaiech return corepll_frequency; 1479b5b5b320SKhalil Blaiech } 1480b5b5b320SKhalil Blaiech 1481b5b5b320SKhalil Blaiech static int mlxbf_i2c_calculate_corepll_freq(struct platform_device *pdev, 1482b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv) 1483b5b5b320SKhalil Blaiech { 1484b5b5b320SKhalil Blaiech const struct mlxbf_i2c_chip_info *chip = priv->chip; 1485b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *corepll_res; 1486b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 1487b5b5b320SKhalil Blaiech u64 *freq = &priv->frequency; 1488b5b5b320SKhalil Blaiech int ret; 1489b5b5b320SKhalil Blaiech 1490b5b5b320SKhalil Blaiech corepll_res = mlxbf_i2c_get_shared_resource(priv, 1491b5b5b320SKhalil Blaiech MLXBF_I2C_COREPLL_RES); 1492b5b5b320SKhalil Blaiech if (!corepll_res) 1493b5b5b320SKhalil Blaiech return -EPERM; 1494b5b5b320SKhalil Blaiech 1495b5b5b320SKhalil Blaiech /* 1496b5b5b320SKhalil Blaiech * First, check whether the TYU core Clock frequency is set. 1497b5b5b320SKhalil Blaiech * The TYU core frequency is the same for all I2C busses; when 1498b5b5b320SKhalil Blaiech * the first device gets probed the frequency is determined and 1499b5b5b320SKhalil Blaiech * stored into a globally visible variable. So, first of all, 1500b5b5b320SKhalil Blaiech * check whether the frequency is already set. Here, we assume 1501b5b5b320SKhalil Blaiech * that the frequency is expected to be greater than 0. 1502b5b5b320SKhalil Blaiech */ 1503b5b5b320SKhalil Blaiech mutex_lock(corepll_res->lock); 1504b5b5b320SKhalil Blaiech if (!mlxbf_i2c_corepll_frequency) { 1505b5b5b320SKhalil Blaiech if (!chip->calculate_freq) { 1506b5b5b320SKhalil Blaiech mutex_unlock(corepll_res->lock); 1507b5b5b320SKhalil Blaiech return -EPERM; 1508b5b5b320SKhalil Blaiech } 1509b5b5b320SKhalil Blaiech 1510b5b5b320SKhalil Blaiech ret = mlxbf_i2c_get_corepll(pdev, priv); 1511b5b5b320SKhalil Blaiech if (ret < 0) { 1512b5b5b320SKhalil Blaiech dev_err(dev, "Failed to get corePLL resource"); 1513b5b5b320SKhalil Blaiech mutex_unlock(corepll_res->lock); 1514b5b5b320SKhalil Blaiech return ret; 1515b5b5b320SKhalil Blaiech } 1516b5b5b320SKhalil Blaiech 1517b5b5b320SKhalil Blaiech mlxbf_i2c_corepll_frequency = chip->calculate_freq(corepll_res); 1518b5b5b320SKhalil Blaiech } 1519b5b5b320SKhalil Blaiech mutex_unlock(corepll_res->lock); 1520b5b5b320SKhalil Blaiech 1521b5b5b320SKhalil Blaiech *freq = mlxbf_i2c_corepll_frequency; 1522b5b5b320SKhalil Blaiech 1523b5b5b320SKhalil Blaiech return 0; 1524b5b5b320SKhalil Blaiech } 1525b5b5b320SKhalil Blaiech 1526b5b5b320SKhalil Blaiech static int mlxbf_slave_enable(struct mlxbf_i2c_priv *priv, u8 addr) 1527b5b5b320SKhalil Blaiech { 1528b5b5b320SKhalil Blaiech u32 slave_reg, slave_reg_tmp, slave_reg_avail, slave_addr_mask; 1529b5b5b320SKhalil Blaiech u8 reg, reg_cnt, byte, addr_tmp, reg_avail, byte_avail; 1530b5b5b320SKhalil Blaiech bool avail, disabled; 1531b5b5b320SKhalil Blaiech 1532b5b5b320SKhalil Blaiech disabled = false; 1533b5b5b320SKhalil Blaiech avail = false; 1534b5b5b320SKhalil Blaiech 1535b5b5b320SKhalil Blaiech if (!priv) 1536b5b5b320SKhalil Blaiech return -EPERM; 1537b5b5b320SKhalil Blaiech 1538b5b5b320SKhalil Blaiech reg_cnt = MLXBF_I2C_SMBUS_SLAVE_ADDR_CNT >> 2; 1539b5b5b320SKhalil Blaiech slave_addr_mask = MLXBF_I2C_SMBUS_SLAVE_ADDR_MASK; 1540b5b5b320SKhalil Blaiech 1541b5b5b320SKhalil Blaiech /* 1542b5b5b320SKhalil Blaiech * Read the slave registers. There are 4 * 32-bit slave registers. 1543b5b5b320SKhalil Blaiech * Each slave register can hold up to 4 * 8-bit slave configuration 1544b5b5b320SKhalil Blaiech * (7-bit address, 1 status bit (1 if enabled, 0 if not)). 1545b5b5b320SKhalil Blaiech */ 1546b5b5b320SKhalil Blaiech for (reg = 0; reg < reg_cnt; reg++) { 15474b19d806SKhalil Blaiech slave_reg = readl(priv->smbus->io + 1548b5b5b320SKhalil Blaiech MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG + reg * 0x4); 1549b5b5b320SKhalil Blaiech /* 1550b5b5b320SKhalil Blaiech * Each register holds 4 slave addresses. So, we have to keep 1551b5b5b320SKhalil Blaiech * the byte order consistent with the value read in order to 1552b5b5b320SKhalil Blaiech * update the register correctly, if needed. 1553b5b5b320SKhalil Blaiech */ 1554b5b5b320SKhalil Blaiech slave_reg_tmp = slave_reg; 1555b5b5b320SKhalil Blaiech for (byte = 0; byte < 4; byte++) { 1556b5b5b320SKhalil Blaiech addr_tmp = slave_reg_tmp & GENMASK(7, 0); 1557b5b5b320SKhalil Blaiech 1558b5b5b320SKhalil Blaiech /* 1559b5b5b320SKhalil Blaiech * Mark the first available slave address slot, i.e. its 1560b5b5b320SKhalil Blaiech * enabled bit should be unset. This slot might be used 1561b5b5b320SKhalil Blaiech * later on to register our slave. 1562b5b5b320SKhalil Blaiech */ 1563b5b5b320SKhalil Blaiech if (!avail && !MLXBF_I2C_SLAVE_ADDR_ENABLED(addr_tmp)) { 1564b5b5b320SKhalil Blaiech avail = true; 1565b5b5b320SKhalil Blaiech reg_avail = reg; 1566b5b5b320SKhalil Blaiech byte_avail = byte; 1567b5b5b320SKhalil Blaiech slave_reg_avail = slave_reg; 1568b5b5b320SKhalil Blaiech } 1569b5b5b320SKhalil Blaiech 1570b5b5b320SKhalil Blaiech /* 1571b5b5b320SKhalil Blaiech * Parse slave address bytes and check whether the 1572b5b5b320SKhalil Blaiech * slave address already exists and it's enabled, 1573b5b5b320SKhalil Blaiech * i.e. most significant bit is set. 1574b5b5b320SKhalil Blaiech */ 1575b5b5b320SKhalil Blaiech if ((addr_tmp & slave_addr_mask) == addr) { 1576b5b5b320SKhalil Blaiech if (MLXBF_I2C_SLAVE_ADDR_ENABLED(addr_tmp)) 1577b5b5b320SKhalil Blaiech return 0; 1578b5b5b320SKhalil Blaiech disabled = true; 1579b5b5b320SKhalil Blaiech break; 1580b5b5b320SKhalil Blaiech } 1581b5b5b320SKhalil Blaiech 1582b5b5b320SKhalil Blaiech /* Parse next byte. */ 1583b5b5b320SKhalil Blaiech slave_reg_tmp >>= 8; 1584b5b5b320SKhalil Blaiech } 1585b5b5b320SKhalil Blaiech 1586b5b5b320SKhalil Blaiech /* Exit the loop if the slave address is found. */ 1587b5b5b320SKhalil Blaiech if (disabled) 1588b5b5b320SKhalil Blaiech break; 1589b5b5b320SKhalil Blaiech } 1590b5b5b320SKhalil Blaiech 1591b5b5b320SKhalil Blaiech if (!avail && !disabled) 1592b5b5b320SKhalil Blaiech return -EINVAL; /* No room for a new slave address. */ 1593b5b5b320SKhalil Blaiech 1594b5b5b320SKhalil Blaiech if (avail && !disabled) { 1595b5b5b320SKhalil Blaiech reg = reg_avail; 1596b5b5b320SKhalil Blaiech byte = byte_avail; 1597b5b5b320SKhalil Blaiech /* Set the slave address. */ 1598b5b5b320SKhalil Blaiech slave_reg_avail &= ~(slave_addr_mask << (byte * 8)); 1599b5b5b320SKhalil Blaiech slave_reg_avail |= addr << (byte * 8); 1600b5b5b320SKhalil Blaiech slave_reg = slave_reg_avail; 1601b5b5b320SKhalil Blaiech } 1602b5b5b320SKhalil Blaiech 1603b5b5b320SKhalil Blaiech /* Enable the slave address and update the register. */ 1604b5b5b320SKhalil Blaiech slave_reg |= (1 << MLXBF_I2C_SMBUS_SLAVE_ADDR_EN_BIT) << (byte * 8); 16054b19d806SKhalil Blaiech writel(slave_reg, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG + 16064b19d806SKhalil Blaiech reg * 0x4); 1607b5b5b320SKhalil Blaiech 1608b5b5b320SKhalil Blaiech return 0; 1609b5b5b320SKhalil Blaiech } 1610b5b5b320SKhalil Blaiech 1611b5b5b320SKhalil Blaiech static int mlxbf_slave_disable(struct mlxbf_i2c_priv *priv) 1612b5b5b320SKhalil Blaiech { 1613b5b5b320SKhalil Blaiech u32 slave_reg, slave_reg_tmp, slave_addr_mask; 1614b5b5b320SKhalil Blaiech u8 addr, addr_tmp, reg, reg_cnt, slave_byte; 1615b5b5b320SKhalil Blaiech struct i2c_client *client = priv->slave; 1616b5b5b320SKhalil Blaiech bool exist; 1617b5b5b320SKhalil Blaiech 1618b5b5b320SKhalil Blaiech exist = false; 1619b5b5b320SKhalil Blaiech 1620b5b5b320SKhalil Blaiech addr = client->addr; 1621b5b5b320SKhalil Blaiech reg_cnt = MLXBF_I2C_SMBUS_SLAVE_ADDR_CNT >> 2; 1622b5b5b320SKhalil Blaiech slave_addr_mask = MLXBF_I2C_SMBUS_SLAVE_ADDR_MASK; 1623b5b5b320SKhalil Blaiech 1624b5b5b320SKhalil Blaiech /* 1625b5b5b320SKhalil Blaiech * Read the slave registers. There are 4 * 32-bit slave registers. 1626b5b5b320SKhalil Blaiech * Each slave register can hold up to 4 * 8-bit slave configuration 1627b5b5b320SKhalil Blaiech * (7-bit address, 1 status bit (1 if enabled, 0 if not)). 1628b5b5b320SKhalil Blaiech */ 1629b5b5b320SKhalil Blaiech for (reg = 0; reg < reg_cnt; reg++) { 16304b19d806SKhalil Blaiech slave_reg = readl(priv->smbus->io + 1631b5b5b320SKhalil Blaiech MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG + reg * 0x4); 1632b5b5b320SKhalil Blaiech 1633b5b5b320SKhalil Blaiech /* Check whether the address slots are empty. */ 1634b5b5b320SKhalil Blaiech if (slave_reg == 0) 1635b5b5b320SKhalil Blaiech continue; 1636b5b5b320SKhalil Blaiech 1637b5b5b320SKhalil Blaiech /* 1638b5b5b320SKhalil Blaiech * Each register holds 4 slave addresses. So, we have to keep 1639b5b5b320SKhalil Blaiech * the byte order consistent with the value read in order to 1640b5b5b320SKhalil Blaiech * update the register correctly, if needed. 1641b5b5b320SKhalil Blaiech */ 1642b5b5b320SKhalil Blaiech slave_reg_tmp = slave_reg; 1643b5b5b320SKhalil Blaiech slave_byte = 0; 1644b5b5b320SKhalil Blaiech while (slave_reg_tmp != 0) { 1645b5b5b320SKhalil Blaiech addr_tmp = slave_reg_tmp & slave_addr_mask; 1646b5b5b320SKhalil Blaiech /* 1647b5b5b320SKhalil Blaiech * Parse slave address bytes and check whether the 1648b5b5b320SKhalil Blaiech * slave address already exists. 1649b5b5b320SKhalil Blaiech */ 1650b5b5b320SKhalil Blaiech if (addr_tmp == addr) { 1651b5b5b320SKhalil Blaiech exist = true; 1652b5b5b320SKhalil Blaiech break; 1653b5b5b320SKhalil Blaiech } 1654b5b5b320SKhalil Blaiech 1655b5b5b320SKhalil Blaiech /* Parse next byte. */ 1656b5b5b320SKhalil Blaiech slave_reg_tmp >>= 8; 1657b5b5b320SKhalil Blaiech slave_byte += 1; 1658b5b5b320SKhalil Blaiech } 1659b5b5b320SKhalil Blaiech 1660b5b5b320SKhalil Blaiech /* Exit the loop if the slave address is found. */ 1661b5b5b320SKhalil Blaiech if (exist) 1662b5b5b320SKhalil Blaiech break; 1663b5b5b320SKhalil Blaiech } 1664b5b5b320SKhalil Blaiech 1665b5b5b320SKhalil Blaiech if (!exist) 1666b5b5b320SKhalil Blaiech return 0; /* Slave is not registered, nothing to do. */ 1667b5b5b320SKhalil Blaiech 1668b5b5b320SKhalil Blaiech /* Cleanup the slave address slot. */ 1669b5b5b320SKhalil Blaiech slave_reg &= ~(GENMASK(7, 0) << (slave_byte * 8)); 16704b19d806SKhalil Blaiech writel(slave_reg, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_ADDR_CFG + 16714b19d806SKhalil Blaiech reg * 0x4); 1672b5b5b320SKhalil Blaiech 1673b5b5b320SKhalil Blaiech return 0; 1674b5b5b320SKhalil Blaiech } 1675b5b5b320SKhalil Blaiech 1676b5b5b320SKhalil Blaiech static int mlxbf_i2c_init_coalesce(struct platform_device *pdev, 1677b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv) 1678b5b5b320SKhalil Blaiech { 1679b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *coalesce_res; 1680b5b5b320SKhalil Blaiech struct resource *params; 1681b5b5b320SKhalil Blaiech resource_size_t size; 1682b5b5b320SKhalil Blaiech int ret = 0; 1683b5b5b320SKhalil Blaiech 1684b5b5b320SKhalil Blaiech /* 1685b5b5b320SKhalil Blaiech * Unlike BlueField-1 platform, the coalesce registers is a dedicated 1686b5b5b320SKhalil Blaiech * resource in the next generations of BlueField. 1687b5b5b320SKhalil Blaiech */ 1688b5b5b320SKhalil Blaiech if (mlxbf_i2c_has_chip_type(priv, MLXBF_I2C_CHIP_TYPE_1)) { 1689b5b5b320SKhalil Blaiech coalesce_res = mlxbf_i2c_get_shared_resource(priv, 1690b5b5b320SKhalil Blaiech MLXBF_I2C_COALESCE_RES); 1691b5b5b320SKhalil Blaiech if (!coalesce_res) 1692b5b5b320SKhalil Blaiech return -EPERM; 1693b5b5b320SKhalil Blaiech 1694b5b5b320SKhalil Blaiech /* 1695b5b5b320SKhalil Blaiech * The Cause Coalesce group in TYU space is shared among 1696b5b5b320SKhalil Blaiech * I2C busses. This function MUST be serialized to avoid 1697b5b5b320SKhalil Blaiech * racing when claiming the memory region. 1698b5b5b320SKhalil Blaiech */ 1699b5b5b320SKhalil Blaiech lockdep_assert_held(mlxbf_i2c_gpio_res->lock); 1700b5b5b320SKhalil Blaiech 1701b5b5b320SKhalil Blaiech /* Check whether the memory map exist. */ 1702b5b5b320SKhalil Blaiech if (coalesce_res->io) { 1703b5b5b320SKhalil Blaiech priv->coalesce = coalesce_res; 1704b5b5b320SKhalil Blaiech return 0; 1705b5b5b320SKhalil Blaiech } 1706b5b5b320SKhalil Blaiech 1707b5b5b320SKhalil Blaiech params = coalesce_res->params; 1708b5b5b320SKhalil Blaiech size = resource_size(params); 1709b5b5b320SKhalil Blaiech 1710b5b5b320SKhalil Blaiech if (!request_mem_region(params->start, size, params->name)) 1711b5b5b320SKhalil Blaiech return -EFAULT; 1712b5b5b320SKhalil Blaiech 1713b5b5b320SKhalil Blaiech coalesce_res->io = ioremap(params->start, size); 17142bf95456SWang Xiaojun if (!coalesce_res->io) { 1715b5b5b320SKhalil Blaiech release_mem_region(params->start, size); 17162bf95456SWang Xiaojun return -ENOMEM; 1717b5b5b320SKhalil Blaiech } 1718b5b5b320SKhalil Blaiech 1719b5b5b320SKhalil Blaiech priv->coalesce = coalesce_res; 1720b5b5b320SKhalil Blaiech 1721b5b5b320SKhalil Blaiech } else { 1722b5b5b320SKhalil Blaiech ret = mlxbf_i2c_init_resource(pdev, &priv->coalesce, 1723b5b5b320SKhalil Blaiech MLXBF_I2C_COALESCE_RES); 1724b5b5b320SKhalil Blaiech } 1725b5b5b320SKhalil Blaiech 1726b5b5b320SKhalil Blaiech return ret; 1727b5b5b320SKhalil Blaiech } 1728b5b5b320SKhalil Blaiech 1729b5b5b320SKhalil Blaiech static int mlxbf_i2c_release_coalesce(struct platform_device *pdev, 1730b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv) 1731b5b5b320SKhalil Blaiech { 1732b5b5b320SKhalil Blaiech struct mlxbf_i2c_resource *coalesce_res; 1733b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 1734b5b5b320SKhalil Blaiech struct resource *params; 1735b5b5b320SKhalil Blaiech resource_size_t size; 1736b5b5b320SKhalil Blaiech 1737b5b5b320SKhalil Blaiech coalesce_res = priv->coalesce; 1738b5b5b320SKhalil Blaiech 1739b5b5b320SKhalil Blaiech if (coalesce_res->io) { 1740b5b5b320SKhalil Blaiech params = coalesce_res->params; 1741b5b5b320SKhalil Blaiech size = resource_size(params); 1742b5b5b320SKhalil Blaiech if (mlxbf_i2c_has_chip_type(priv, MLXBF_I2C_CHIP_TYPE_1)) { 1743b5b5b320SKhalil Blaiech mutex_lock(coalesce_res->lock); 1744b5b5b320SKhalil Blaiech iounmap(coalesce_res->io); 1745b5b5b320SKhalil Blaiech release_mem_region(params->start, size); 1746b5b5b320SKhalil Blaiech mutex_unlock(coalesce_res->lock); 1747b5b5b320SKhalil Blaiech } else { 1748b5b5b320SKhalil Blaiech devm_release_mem_region(dev, params->start, size); 1749b5b5b320SKhalil Blaiech } 1750b5b5b320SKhalil Blaiech } 1751b5b5b320SKhalil Blaiech 1752b5b5b320SKhalil Blaiech return 0; 1753b5b5b320SKhalil Blaiech } 1754b5b5b320SKhalil Blaiech 1755b5b5b320SKhalil Blaiech static int mlxbf_i2c_init_slave(struct platform_device *pdev, 1756b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv) 1757b5b5b320SKhalil Blaiech { 1758b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 1759b5b5b320SKhalil Blaiech u32 int_reg; 1760b5b5b320SKhalil Blaiech int ret; 1761b5b5b320SKhalil Blaiech 1762b5b5b320SKhalil Blaiech /* Reset FSM. */ 17634b19d806SKhalil Blaiech writel(0, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_FSM); 1764b5b5b320SKhalil Blaiech 1765b5b5b320SKhalil Blaiech /* 1766b5b5b320SKhalil Blaiech * Enable slave cause interrupt bits. Drive 1767b5b5b320SKhalil Blaiech * MLXBF_I2C_CAUSE_READ_WAIT_FW_RESPONSE and 1768b5b5b320SKhalil Blaiech * MLXBF_I2C_CAUSE_WRITE_SUCCESS, these are enabled when an external 1769b5b5b320SKhalil Blaiech * masters issue a Read and Write, respectively. But, clear all 1770b5b5b320SKhalil Blaiech * interrupts first. 1771b5b5b320SKhalil Blaiech */ 17724b19d806SKhalil Blaiech writel(~0, priv->slv_cause->io + MLXBF_I2C_CAUSE_OR_CLEAR); 1773b5b5b320SKhalil Blaiech int_reg = MLXBF_I2C_CAUSE_READ_WAIT_FW_RESPONSE; 1774b5b5b320SKhalil Blaiech int_reg |= MLXBF_I2C_CAUSE_WRITE_SUCCESS; 17754b19d806SKhalil Blaiech writel(int_reg, priv->slv_cause->io + MLXBF_I2C_CAUSE_OR_EVTEN0); 1776b5b5b320SKhalil Blaiech 1777b5b5b320SKhalil Blaiech /* Finally, set the 'ready' bit to start handling transactions. */ 17784b19d806SKhalil Blaiech writel(0x1, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_READY); 1779b5b5b320SKhalil Blaiech 1780b5b5b320SKhalil Blaiech /* Initialize the cause coalesce resource. */ 1781b5b5b320SKhalil Blaiech ret = mlxbf_i2c_init_coalesce(pdev, priv); 1782b5b5b320SKhalil Blaiech if (ret < 0) { 1783b5b5b320SKhalil Blaiech dev_err(dev, "failed to initialize cause coalesce\n"); 1784b5b5b320SKhalil Blaiech return ret; 1785b5b5b320SKhalil Blaiech } 1786b5b5b320SKhalil Blaiech 1787b5b5b320SKhalil Blaiech return 0; 1788b5b5b320SKhalil Blaiech } 1789b5b5b320SKhalil Blaiech 1790b5b5b320SKhalil Blaiech static bool mlxbf_i2c_has_coalesce(struct mlxbf_i2c_priv *priv, bool *read, 1791b5b5b320SKhalil Blaiech bool *write) 1792b5b5b320SKhalil Blaiech { 1793b5b5b320SKhalil Blaiech const struct mlxbf_i2c_chip_info *chip = priv->chip; 1794b5b5b320SKhalil Blaiech u32 coalesce0_reg, cause_reg; 1795b5b5b320SKhalil Blaiech u8 slave_shift, is_set; 1796b5b5b320SKhalil Blaiech 1797b5b5b320SKhalil Blaiech *write = false; 1798b5b5b320SKhalil Blaiech *read = false; 1799b5b5b320SKhalil Blaiech 1800b5b5b320SKhalil Blaiech slave_shift = chip->type != MLXBF_I2C_CHIP_TYPE_1 ? 1801b5b5b320SKhalil Blaiech MLXBF_I2C_CAUSE_YU_SLAVE_BIT : 1802b5b5b320SKhalil Blaiech priv->bus + MLXBF_I2C_CAUSE_TYU_SLAVE_BIT; 1803b5b5b320SKhalil Blaiech 18044b19d806SKhalil Blaiech coalesce0_reg = readl(priv->coalesce->io + MLXBF_I2C_CAUSE_COALESCE_0); 1805b5b5b320SKhalil Blaiech is_set = coalesce0_reg & (1 << slave_shift); 1806b5b5b320SKhalil Blaiech 1807b5b5b320SKhalil Blaiech if (!is_set) 1808b5b5b320SKhalil Blaiech return false; 1809b5b5b320SKhalil Blaiech 1810b5b5b320SKhalil Blaiech /* Check the source of the interrupt, i.e. whether a Read or Write. */ 18114b19d806SKhalil Blaiech cause_reg = readl(priv->slv_cause->io + MLXBF_I2C_CAUSE_ARBITER); 1812b5b5b320SKhalil Blaiech if (cause_reg & MLXBF_I2C_CAUSE_READ_WAIT_FW_RESPONSE) 1813b5b5b320SKhalil Blaiech *read = true; 1814b5b5b320SKhalil Blaiech else if (cause_reg & MLXBF_I2C_CAUSE_WRITE_SUCCESS) 1815b5b5b320SKhalil Blaiech *write = true; 1816b5b5b320SKhalil Blaiech 1817b5b5b320SKhalil Blaiech /* Clear cause bits. */ 18184b19d806SKhalil Blaiech writel(~0x0, priv->slv_cause->io + MLXBF_I2C_CAUSE_OR_CLEAR); 1819b5b5b320SKhalil Blaiech 1820b5b5b320SKhalil Blaiech return true; 1821b5b5b320SKhalil Blaiech } 1822b5b5b320SKhalil Blaiech 1823b5b5b320SKhalil Blaiech static bool mlxbf_smbus_slave_wait_for_idle(struct mlxbf_i2c_priv *priv, 1824b5b5b320SKhalil Blaiech u32 timeout) 1825b5b5b320SKhalil Blaiech { 1826b5b5b320SKhalil Blaiech u32 mask = MLXBF_I2C_CAUSE_S_GW_BUSY_FALL; 1827b5b5b320SKhalil Blaiech u32 addr = MLXBF_I2C_CAUSE_ARBITER; 1828b5b5b320SKhalil Blaiech 1829b5b5b320SKhalil Blaiech if (mlxbf_smbus_poll(priv->slv_cause->io, addr, mask, false, timeout)) 1830b5b5b320SKhalil Blaiech return true; 1831b5b5b320SKhalil Blaiech 1832b5b5b320SKhalil Blaiech return false; 1833b5b5b320SKhalil Blaiech } 1834b5b5b320SKhalil Blaiech 1835b5b5b320SKhalil Blaiech /* Send byte to 'external' smbus master. */ 1836b5b5b320SKhalil Blaiech static int mlxbf_smbus_irq_send(struct mlxbf_i2c_priv *priv, u8 recv_bytes) 1837b5b5b320SKhalil Blaiech { 1838b5b5b320SKhalil Blaiech u8 data_desc[MLXBF_I2C_SLAVE_DATA_DESC_SIZE] = { 0 }; 1839b5b5b320SKhalil Blaiech u8 write_size, pec_en, addr, byte, value, byte_cnt, desc_size; 1840b5b5b320SKhalil Blaiech struct i2c_client *slave = priv->slave; 1841b5b5b320SKhalil Blaiech u32 control32, data32; 1842b5b5b320SKhalil Blaiech int ret; 1843b5b5b320SKhalil Blaiech 1844b5b5b320SKhalil Blaiech if (!slave) 1845b5b5b320SKhalil Blaiech return -EINVAL; 1846b5b5b320SKhalil Blaiech 1847b5b5b320SKhalil Blaiech addr = 0; 1848b5b5b320SKhalil Blaiech byte = 0; 1849b5b5b320SKhalil Blaiech desc_size = MLXBF_I2C_SLAVE_DATA_DESC_SIZE; 1850b5b5b320SKhalil Blaiech 1851b5b5b320SKhalil Blaiech /* 1852b5b5b320SKhalil Blaiech * Read bytes received from the external master. These bytes should 1853b5b5b320SKhalil Blaiech * be located in the first data descriptor register of the slave GW. 1854b5b5b320SKhalil Blaiech * These bytes are the slave address byte and the internal register 1855b5b5b320SKhalil Blaiech * address, if supplied. 1856b5b5b320SKhalil Blaiech */ 1857b5b5b320SKhalil Blaiech if (recv_bytes > 0) { 18584b19d806SKhalil Blaiech data32 = ioread32be(priv->smbus->io + 1859b5b5b320SKhalil Blaiech MLXBF_I2C_SLAVE_DATA_DESC_ADDR); 1860b5b5b320SKhalil Blaiech 1861b5b5b320SKhalil Blaiech /* Parse the received bytes. */ 1862b5b5b320SKhalil Blaiech switch (recv_bytes) { 1863b5b5b320SKhalil Blaiech case 2: 1864b5b5b320SKhalil Blaiech byte = (data32 >> 8) & GENMASK(7, 0); 1865b5b5b320SKhalil Blaiech fallthrough; 1866b5b5b320SKhalil Blaiech case 1: 1867b5b5b320SKhalil Blaiech addr = (data32 & GENMASK(7, 0)) >> 1; 1868b5b5b320SKhalil Blaiech } 1869b5b5b320SKhalil Blaiech 1870b5b5b320SKhalil Blaiech /* Check whether it's our slave address. */ 1871b5b5b320SKhalil Blaiech if (slave->addr != addr) 1872b5b5b320SKhalil Blaiech return -EINVAL; 1873b5b5b320SKhalil Blaiech } 1874b5b5b320SKhalil Blaiech 1875b5b5b320SKhalil Blaiech /* 1876b5b5b320SKhalil Blaiech * I2C read transactions may start by a WRITE followed by a READ. 1877b5b5b320SKhalil Blaiech * Indeed, most slave devices would expect the internal address 1878b5b5b320SKhalil Blaiech * following the slave address byte. So, write that byte first, 1879b5b5b320SKhalil Blaiech * and then, send the requested data bytes to the master. 1880b5b5b320SKhalil Blaiech */ 1881b5b5b320SKhalil Blaiech if (recv_bytes > 1) { 1882b5b5b320SKhalil Blaiech i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value); 1883b5b5b320SKhalil Blaiech value = byte; 1884b5b5b320SKhalil Blaiech ret = i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, 1885b5b5b320SKhalil Blaiech &value); 1886b5b5b320SKhalil Blaiech i2c_slave_event(slave, I2C_SLAVE_STOP, &value); 1887b5b5b320SKhalil Blaiech 1888b5b5b320SKhalil Blaiech if (ret < 0) 1889b5b5b320SKhalil Blaiech return ret; 1890b5b5b320SKhalil Blaiech } 1891b5b5b320SKhalil Blaiech 1892b5b5b320SKhalil Blaiech /* 1893b5b5b320SKhalil Blaiech * Now, send data to the master; currently, the driver supports 1894b5b5b320SKhalil Blaiech * READ_BYTE, READ_WORD and BLOCK READ protocols. Note that the 1895b5b5b320SKhalil Blaiech * hardware can send up to 128 bytes per transfer. That is the 1896b5b5b320SKhalil Blaiech * size of its data registers. 1897b5b5b320SKhalil Blaiech */ 1898b5b5b320SKhalil Blaiech i2c_slave_event(slave, I2C_SLAVE_READ_REQUESTED, &value); 1899b5b5b320SKhalil Blaiech 1900b5b5b320SKhalil Blaiech for (byte_cnt = 0; byte_cnt < desc_size; byte_cnt++) { 1901b5b5b320SKhalil Blaiech data_desc[byte_cnt] = value; 1902b5b5b320SKhalil Blaiech i2c_slave_event(slave, I2C_SLAVE_READ_PROCESSED, &value); 1903b5b5b320SKhalil Blaiech } 1904b5b5b320SKhalil Blaiech 1905b5b5b320SKhalil Blaiech /* Send a stop condition to the backend. */ 1906b5b5b320SKhalil Blaiech i2c_slave_event(slave, I2C_SLAVE_STOP, &value); 1907b5b5b320SKhalil Blaiech 1908b5b5b320SKhalil Blaiech /* Handle the actual transfer. */ 1909b5b5b320SKhalil Blaiech 1910b5b5b320SKhalil Blaiech /* Set the number of bytes to write to master. */ 1911b5b5b320SKhalil Blaiech write_size = (byte_cnt - 1) & 0x7f; 1912b5b5b320SKhalil Blaiech 1913b5b5b320SKhalil Blaiech /* Write data to Slave GW data descriptor. */ 1914b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_write_data(priv, data_desc, byte_cnt, 1915b5b5b320SKhalil Blaiech MLXBF_I2C_SLAVE_DATA_DESC_ADDR); 1916b5b5b320SKhalil Blaiech 1917b5b5b320SKhalil Blaiech pec_en = 0; /* Disable PEC since it is not supported. */ 1918b5b5b320SKhalil Blaiech 1919b5b5b320SKhalil Blaiech /* Prepare control word. */ 1920b5b5b320SKhalil Blaiech control32 = MLXBF_I2C_SLAVE_ENABLE; 1921b5b5b320SKhalil Blaiech control32 |= rol32(write_size, MLXBF_I2C_SLAVE_WRITE_BYTES_SHIFT); 1922b5b5b320SKhalil Blaiech control32 |= rol32(pec_en, MLXBF_I2C_SLAVE_SEND_PEC_SHIFT); 1923b5b5b320SKhalil Blaiech 19244b19d806SKhalil Blaiech writel(control32, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_GW); 1925b5b5b320SKhalil Blaiech 1926b5b5b320SKhalil Blaiech /* 1927b5b5b320SKhalil Blaiech * Wait until the transfer is completed; the driver will wait 1928b5b5b320SKhalil Blaiech * until the GW is idle, a cause will rise on fall of GW busy. 1929b5b5b320SKhalil Blaiech */ 1930b5b5b320SKhalil Blaiech mlxbf_smbus_slave_wait_for_idle(priv, MLXBF_I2C_SMBUS_TIMEOUT); 1931b5b5b320SKhalil Blaiech 1932b5b5b320SKhalil Blaiech /* Release the Slave GW. */ 19334b19d806SKhalil Blaiech writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES); 19344b19d806SKhalil Blaiech writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_PEC); 19354b19d806SKhalil Blaiech writel(0x1, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_READY); 1936b5b5b320SKhalil Blaiech 1937b5b5b320SKhalil Blaiech return 0; 1938b5b5b320SKhalil Blaiech } 1939b5b5b320SKhalil Blaiech 1940b5b5b320SKhalil Blaiech /* Receive bytes from 'external' smbus master. */ 1941b5b5b320SKhalil Blaiech static int mlxbf_smbus_irq_recv(struct mlxbf_i2c_priv *priv, u8 recv_bytes) 1942b5b5b320SKhalil Blaiech { 1943b5b5b320SKhalil Blaiech u8 data_desc[MLXBF_I2C_SLAVE_DATA_DESC_SIZE] = { 0 }; 1944b5b5b320SKhalil Blaiech struct i2c_client *slave = priv->slave; 1945b5b5b320SKhalil Blaiech u8 value, byte, addr; 1946b5b5b320SKhalil Blaiech int ret = 0; 1947b5b5b320SKhalil Blaiech 1948b5b5b320SKhalil Blaiech if (!slave) 1949b5b5b320SKhalil Blaiech return -EINVAL; 1950b5b5b320SKhalil Blaiech 1951b5b5b320SKhalil Blaiech /* Read data from Slave GW data descriptor. */ 1952b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_read_data(priv, data_desc, recv_bytes, 1953b5b5b320SKhalil Blaiech MLXBF_I2C_SLAVE_DATA_DESC_ADDR); 1954b5b5b320SKhalil Blaiech 1955b5b5b320SKhalil Blaiech /* Check whether its our slave address. */ 1956b5b5b320SKhalil Blaiech addr = data_desc[0] >> 1; 1957b5b5b320SKhalil Blaiech if (slave->addr != addr) 1958b5b5b320SKhalil Blaiech return -EINVAL; 1959b5b5b320SKhalil Blaiech 1960b5b5b320SKhalil Blaiech /* 1961b5b5b320SKhalil Blaiech * Notify the slave backend; another I2C master wants to write data 1962b5b5b320SKhalil Blaiech * to us. This event is sent once the slave address and the write bit 1963b5b5b320SKhalil Blaiech * is detected. 1964b5b5b320SKhalil Blaiech */ 1965b5b5b320SKhalil Blaiech i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value); 1966b5b5b320SKhalil Blaiech 1967b5b5b320SKhalil Blaiech /* Send the received data to the slave backend. */ 1968b5b5b320SKhalil Blaiech for (byte = 1; byte < recv_bytes; byte++) { 1969b5b5b320SKhalil Blaiech value = data_desc[byte]; 1970b5b5b320SKhalil Blaiech ret = i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, 1971b5b5b320SKhalil Blaiech &value); 1972b5b5b320SKhalil Blaiech if (ret < 0) 1973b5b5b320SKhalil Blaiech break; 1974b5b5b320SKhalil Blaiech } 1975b5b5b320SKhalil Blaiech 1976b5b5b320SKhalil Blaiech /* Send a stop condition to the backend. */ 1977b5b5b320SKhalil Blaiech i2c_slave_event(slave, I2C_SLAVE_STOP, &value); 1978b5b5b320SKhalil Blaiech 1979b5b5b320SKhalil Blaiech /* Release the Slave GW. */ 19804b19d806SKhalil Blaiech writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES); 19814b19d806SKhalil Blaiech writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_PEC); 19824b19d806SKhalil Blaiech writel(0x1, priv->smbus->io + MLXBF_I2C_SMBUS_SLAVE_READY); 1983b5b5b320SKhalil Blaiech 1984b5b5b320SKhalil Blaiech return ret; 1985b5b5b320SKhalil Blaiech } 1986b5b5b320SKhalil Blaiech 1987b5b5b320SKhalil Blaiech static irqreturn_t mlxbf_smbus_irq(int irq, void *ptr) 1988b5b5b320SKhalil Blaiech { 1989b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv = ptr; 1990b5b5b320SKhalil Blaiech bool read, write, irq_is_set; 1991b5b5b320SKhalil Blaiech u32 rw_bytes_reg; 1992b5b5b320SKhalil Blaiech u8 recv_bytes; 1993b5b5b320SKhalil Blaiech 1994b5b5b320SKhalil Blaiech /* 1995b5b5b320SKhalil Blaiech * Read TYU interrupt register and determine the source of the 1996b5b5b320SKhalil Blaiech * interrupt. Based on the source of the interrupt one of the 1997b5b5b320SKhalil Blaiech * following actions are performed: 1998b5b5b320SKhalil Blaiech * - Receive data and send response to master. 1999b5b5b320SKhalil Blaiech * - Send data and release slave GW. 2000b5b5b320SKhalil Blaiech * 2001b5b5b320SKhalil Blaiech * Handle read/write transaction only. CRmaster and Iarp requests 2002b5b5b320SKhalil Blaiech * are ignored for now. 2003b5b5b320SKhalil Blaiech */ 2004b5b5b320SKhalil Blaiech irq_is_set = mlxbf_i2c_has_coalesce(priv, &read, &write); 2005b5b5b320SKhalil Blaiech if (!irq_is_set || (!read && !write)) { 2006b5b5b320SKhalil Blaiech /* Nothing to do here, interrupt was not from this device. */ 2007b5b5b320SKhalil Blaiech return IRQ_NONE; 2008b5b5b320SKhalil Blaiech } 2009b5b5b320SKhalil Blaiech 2010b5b5b320SKhalil Blaiech /* 2011b5b5b320SKhalil Blaiech * The MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES includes the number of 2012b5b5b320SKhalil Blaiech * bytes from/to master. These are defined by 8-bits each. If the lower 2013b5b5b320SKhalil Blaiech * 8 bits are set, then the master expect to read N bytes from the 2014b5b5b320SKhalil Blaiech * slave, if the higher 8 bits are sent then the slave expect N bytes 2015b5b5b320SKhalil Blaiech * from the master. 2016b5b5b320SKhalil Blaiech */ 20174b19d806SKhalil Blaiech rw_bytes_reg = readl(priv->smbus->io + 2018b5b5b320SKhalil Blaiech MLXBF_I2C_SMBUS_SLAVE_RS_MASTER_BYTES); 2019b5b5b320SKhalil Blaiech recv_bytes = (rw_bytes_reg >> 8) & GENMASK(7, 0); 2020b5b5b320SKhalil Blaiech 2021b5b5b320SKhalil Blaiech /* 2022b5b5b320SKhalil Blaiech * For now, the slave supports 128 bytes transfer. Discard remaining 2023b5b5b320SKhalil Blaiech * data bytes if the master wrote more than 2024b5b5b320SKhalil Blaiech * MLXBF_I2C_SLAVE_DATA_DESC_SIZE, i.e, the actual size of the slave 2025b5b5b320SKhalil Blaiech * data descriptor. 2026b5b5b320SKhalil Blaiech * 2027b5b5b320SKhalil Blaiech * Note that we will never expect to transfer more than 128 bytes; as 2028b5b5b320SKhalil Blaiech * specified in the SMBus standard, block transactions cannot exceed 2029b5b5b320SKhalil Blaiech * 32 bytes. 2030b5b5b320SKhalil Blaiech */ 2031b5b5b320SKhalil Blaiech recv_bytes = recv_bytes > MLXBF_I2C_SLAVE_DATA_DESC_SIZE ? 2032b5b5b320SKhalil Blaiech MLXBF_I2C_SLAVE_DATA_DESC_SIZE : recv_bytes; 2033b5b5b320SKhalil Blaiech 2034b5b5b320SKhalil Blaiech if (read) 2035b5b5b320SKhalil Blaiech mlxbf_smbus_irq_send(priv, recv_bytes); 2036b5b5b320SKhalil Blaiech else 2037b5b5b320SKhalil Blaiech mlxbf_smbus_irq_recv(priv, recv_bytes); 2038b5b5b320SKhalil Blaiech 2039b5b5b320SKhalil Blaiech return IRQ_HANDLED; 2040b5b5b320SKhalil Blaiech } 2041b5b5b320SKhalil Blaiech 2042b5b5b320SKhalil Blaiech /* Return negative errno on error. */ 2043b5b5b320SKhalil Blaiech static s32 mlxbf_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, 2044b5b5b320SKhalil Blaiech unsigned short flags, char read_write, 2045b5b5b320SKhalil Blaiech u8 command, int size, 2046b5b5b320SKhalil Blaiech union i2c_smbus_data *data) 2047b5b5b320SKhalil Blaiech { 2048b5b5b320SKhalil Blaiech struct mlxbf_i2c_smbus_request request = { 0 }; 2049b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv; 2050b5b5b320SKhalil Blaiech bool read, pec; 2051b5b5b320SKhalil Blaiech u8 byte_cnt; 2052b5b5b320SKhalil Blaiech 2053b5b5b320SKhalil Blaiech request.slave = addr; 2054b5b5b320SKhalil Blaiech 2055b5b5b320SKhalil Blaiech read = (read_write == I2C_SMBUS_READ); 2056b5b5b320SKhalil Blaiech pec = flags & I2C_FUNC_SMBUS_PEC; 2057b5b5b320SKhalil Blaiech 2058b5b5b320SKhalil Blaiech switch (size) { 2059b5b5b320SKhalil Blaiech case I2C_SMBUS_QUICK: 2060b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_quick_command(&request, read); 2061b5b5b320SKhalil Blaiech dev_dbg(&adap->dev, "smbus quick, slave 0x%02x\n", addr); 2062b5b5b320SKhalil Blaiech break; 2063b5b5b320SKhalil Blaiech 2064b5b5b320SKhalil Blaiech case I2C_SMBUS_BYTE: 2065b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_byte_func(&request, 2066b5b5b320SKhalil Blaiech read ? &data->byte : &command, read, 2067b5b5b320SKhalil Blaiech pec); 2068b5b5b320SKhalil Blaiech dev_dbg(&adap->dev, "smbus %s byte, slave 0x%02x.\n", 2069b5b5b320SKhalil Blaiech read ? "read" : "write", addr); 2070b5b5b320SKhalil Blaiech break; 2071b5b5b320SKhalil Blaiech 2072b5b5b320SKhalil Blaiech case I2C_SMBUS_BYTE_DATA: 2073b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_data_byte_func(&request, &command, &data->byte, 2074b5b5b320SKhalil Blaiech read, pec); 2075b5b5b320SKhalil Blaiech dev_dbg(&adap->dev, "smbus %s byte data at 0x%02x, slave 0x%02x.\n", 2076b5b5b320SKhalil Blaiech read ? "read" : "write", command, addr); 2077b5b5b320SKhalil Blaiech break; 2078b5b5b320SKhalil Blaiech 2079b5b5b320SKhalil Blaiech case I2C_SMBUS_WORD_DATA: 2080b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_data_word_func(&request, &command, 2081b5b5b320SKhalil Blaiech (u8 *)&data->word, read, pec); 2082b5b5b320SKhalil Blaiech dev_dbg(&adap->dev, "smbus %s word data at 0x%02x, slave 0x%02x.\n", 2083b5b5b320SKhalil Blaiech read ? "read" : "write", command, addr); 2084b5b5b320SKhalil Blaiech break; 2085b5b5b320SKhalil Blaiech 2086b5b5b320SKhalil Blaiech case I2C_SMBUS_I2C_BLOCK_DATA: 2087b5b5b320SKhalil Blaiech byte_cnt = data->block[0]; 2088b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_i2c_block_func(&request, &command, data->block, 2089b5b5b320SKhalil Blaiech &byte_cnt, read, pec); 2090b5b5b320SKhalil Blaiech dev_dbg(&adap->dev, "i2c %s block data, %d bytes at 0x%02x, slave 0x%02x.\n", 2091b5b5b320SKhalil Blaiech read ? "read" : "write", byte_cnt, command, addr); 2092b5b5b320SKhalil Blaiech break; 2093b5b5b320SKhalil Blaiech 2094b5b5b320SKhalil Blaiech case I2C_SMBUS_BLOCK_DATA: 2095b5b5b320SKhalil Blaiech byte_cnt = read ? I2C_SMBUS_BLOCK_MAX : data->block[0]; 2096b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_block_func(&request, &command, data->block, 2097b5b5b320SKhalil Blaiech &byte_cnt, read, pec); 2098b5b5b320SKhalil Blaiech dev_dbg(&adap->dev, "smbus %s block data, %d bytes at 0x%02x, slave 0x%02x.\n", 2099b5b5b320SKhalil Blaiech read ? "read" : "write", byte_cnt, command, addr); 2100b5b5b320SKhalil Blaiech break; 2101b5b5b320SKhalil Blaiech 2102b5b5b320SKhalil Blaiech case I2C_FUNC_SMBUS_PROC_CALL: 2103b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_process_call_func(&request, &command, 2104b5b5b320SKhalil Blaiech (u8 *)&data->word, pec); 2105b5b5b320SKhalil Blaiech dev_dbg(&adap->dev, "process call, wr/rd at 0x%02x, slave 0x%02x.\n", 2106b5b5b320SKhalil Blaiech command, addr); 2107b5b5b320SKhalil Blaiech break; 2108b5b5b320SKhalil Blaiech 2109b5b5b320SKhalil Blaiech case I2C_FUNC_SMBUS_BLOCK_PROC_CALL: 2110b5b5b320SKhalil Blaiech byte_cnt = data->block[0]; 2111b5b5b320SKhalil Blaiech mlxbf_i2c_smbus_blk_process_call_func(&request, &command, 2112b5b5b320SKhalil Blaiech data->block, &byte_cnt, 2113b5b5b320SKhalil Blaiech pec); 2114b5b5b320SKhalil Blaiech dev_dbg(&adap->dev, "block process call, wr/rd %d bytes, slave 0x%02x.\n", 2115b5b5b320SKhalil Blaiech byte_cnt, addr); 2116b5b5b320SKhalil Blaiech break; 2117b5b5b320SKhalil Blaiech 2118b5b5b320SKhalil Blaiech default: 2119b5b5b320SKhalil Blaiech dev_dbg(&adap->dev, "Unsupported I2C/SMBus command %d\n", 2120b5b5b320SKhalil Blaiech size); 2121b5b5b320SKhalil Blaiech return -EOPNOTSUPP; 2122b5b5b320SKhalil Blaiech } 2123b5b5b320SKhalil Blaiech 2124b5b5b320SKhalil Blaiech priv = i2c_get_adapdata(adap); 2125b5b5b320SKhalil Blaiech 2126b5b5b320SKhalil Blaiech return mlxbf_i2c_smbus_start_transaction(priv, &request); 2127b5b5b320SKhalil Blaiech } 2128b5b5b320SKhalil Blaiech 2129b5b5b320SKhalil Blaiech static int mlxbf_i2c_reg_slave(struct i2c_client *slave) 2130b5b5b320SKhalil Blaiech { 2131b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv = i2c_get_adapdata(slave->adapter); 2132b5b5b320SKhalil Blaiech int ret; 2133b5b5b320SKhalil Blaiech 2134b5b5b320SKhalil Blaiech if (priv->slave) 2135b5b5b320SKhalil Blaiech return -EBUSY; 2136b5b5b320SKhalil Blaiech 2137b5b5b320SKhalil Blaiech /* 2138b5b5b320SKhalil Blaiech * Do not support ten bit chip address and do not use Packet Error 2139b5b5b320SKhalil Blaiech * Checking (PEC). 2140b5b5b320SKhalil Blaiech */ 2141b5b5b320SKhalil Blaiech if (slave->flags & (I2C_CLIENT_TEN | I2C_CLIENT_PEC)) 2142b5b5b320SKhalil Blaiech return -EAFNOSUPPORT; 2143b5b5b320SKhalil Blaiech 2144b5b5b320SKhalil Blaiech ret = mlxbf_slave_enable(priv, slave->addr); 2145b5b5b320SKhalil Blaiech if (ret < 0) 2146b5b5b320SKhalil Blaiech return ret; 2147b5b5b320SKhalil Blaiech 2148b5b5b320SKhalil Blaiech priv->slave = slave; 2149b5b5b320SKhalil Blaiech 2150b5b5b320SKhalil Blaiech return 0; 2151b5b5b320SKhalil Blaiech } 2152b5b5b320SKhalil Blaiech 2153b5b5b320SKhalil Blaiech static int mlxbf_i2c_unreg_slave(struct i2c_client *slave) 2154b5b5b320SKhalil Blaiech { 2155b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv = i2c_get_adapdata(slave->adapter); 2156b5b5b320SKhalil Blaiech int ret; 2157b5b5b320SKhalil Blaiech 2158b5b5b320SKhalil Blaiech WARN_ON(!priv->slave); 2159b5b5b320SKhalil Blaiech 2160b5b5b320SKhalil Blaiech /* Unregister slave, i.e. disable the slave address in hardware. */ 2161b5b5b320SKhalil Blaiech ret = mlxbf_slave_disable(priv); 2162b5b5b320SKhalil Blaiech if (ret < 0) 2163b5b5b320SKhalil Blaiech return ret; 2164b5b5b320SKhalil Blaiech 2165b5b5b320SKhalil Blaiech priv->slave = NULL; 2166b5b5b320SKhalil Blaiech 2167b5b5b320SKhalil Blaiech return 0; 2168b5b5b320SKhalil Blaiech } 2169b5b5b320SKhalil Blaiech 2170b5b5b320SKhalil Blaiech static u32 mlxbf_i2c_functionality(struct i2c_adapter *adap) 2171b5b5b320SKhalil Blaiech { 2172b5b5b320SKhalil Blaiech return MLXBF_I2C_FUNC_ALL; 2173b5b5b320SKhalil Blaiech } 2174b5b5b320SKhalil Blaiech 2175b5b5b320SKhalil Blaiech static struct mlxbf_i2c_chip_info mlxbf_i2c_chip[] = { 2176b5b5b320SKhalil Blaiech [MLXBF_I2C_CHIP_TYPE_1] = { 2177b5b5b320SKhalil Blaiech .type = MLXBF_I2C_CHIP_TYPE_1, 2178b5b5b320SKhalil Blaiech .shared_res = { 2179b5b5b320SKhalil Blaiech [0] = &mlxbf_i2c_coalesce_res[MLXBF_I2C_CHIP_TYPE_1], 2180b5b5b320SKhalil Blaiech [1] = &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_1], 2181b5b5b320SKhalil Blaiech [2] = &mlxbf_i2c_gpio_res[MLXBF_I2C_CHIP_TYPE_1] 2182b5b5b320SKhalil Blaiech }, 2183b5b5b320SKhalil Blaiech .calculate_freq = mlxbf_calculate_freq_from_tyu 2184b5b5b320SKhalil Blaiech }, 2185b5b5b320SKhalil Blaiech [MLXBF_I2C_CHIP_TYPE_2] = { 2186b5b5b320SKhalil Blaiech .type = MLXBF_I2C_CHIP_TYPE_2, 2187b5b5b320SKhalil Blaiech .shared_res = { 2188b5b5b320SKhalil Blaiech [0] = &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_2] 2189b5b5b320SKhalil Blaiech }, 2190b5b5b320SKhalil Blaiech .calculate_freq = mlxbf_calculate_freq_from_yu 2191b5b5b320SKhalil Blaiech } 2192b5b5b320SKhalil Blaiech }; 2193b5b5b320SKhalil Blaiech 2194b5b5b320SKhalil Blaiech static const struct i2c_algorithm mlxbf_i2c_algo = { 2195b5b5b320SKhalil Blaiech .smbus_xfer = mlxbf_i2c_smbus_xfer, 2196b5b5b320SKhalil Blaiech .functionality = mlxbf_i2c_functionality, 2197b5b5b320SKhalil Blaiech .reg_slave = mlxbf_i2c_reg_slave, 2198b5b5b320SKhalil Blaiech .unreg_slave = mlxbf_i2c_unreg_slave, 2199b5b5b320SKhalil Blaiech }; 2200b5b5b320SKhalil Blaiech 2201b5b5b320SKhalil Blaiech static struct i2c_adapter_quirks mlxbf_i2c_quirks = { 2202b5b5b320SKhalil Blaiech .max_read_len = MLXBF_I2C_MASTER_DATA_R_LENGTH, 2203b5b5b320SKhalil Blaiech .max_write_len = MLXBF_I2C_MASTER_DATA_W_LENGTH, 2204b5b5b320SKhalil Blaiech }; 2205b5b5b320SKhalil Blaiech 2206b5b5b320SKhalil Blaiech static const struct of_device_id mlxbf_i2c_dt_ids[] = { 2207b5b5b320SKhalil Blaiech { 2208b5b5b320SKhalil Blaiech .compatible = "mellanox,i2c-mlxbf1", 2209b5b5b320SKhalil Blaiech .data = &mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_1] 2210b5b5b320SKhalil Blaiech }, 2211b5b5b320SKhalil Blaiech { 2212b5b5b320SKhalil Blaiech .compatible = "mellanox,i2c-mlxbf2", 2213b5b5b320SKhalil Blaiech .data = &mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_2] 2214b5b5b320SKhalil Blaiech }, 2215b5b5b320SKhalil Blaiech {}, 2216b5b5b320SKhalil Blaiech }; 2217b5b5b320SKhalil Blaiech 2218b5b5b320SKhalil Blaiech MODULE_DEVICE_TABLE(of, mlxbf_i2c_dt_ids); 2219b5b5b320SKhalil Blaiech 2220ed01ddc6SKhalil Blaiech #ifdef CONFIG_ACPI 2221b5b5b320SKhalil Blaiech static const struct acpi_device_id mlxbf_i2c_acpi_ids[] = { 2222b5b5b320SKhalil Blaiech { "MLNXBF03", (kernel_ulong_t)&mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_1] }, 2223b5b5b320SKhalil Blaiech { "MLNXBF23", (kernel_ulong_t)&mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_2] }, 2224b5b5b320SKhalil Blaiech {}, 2225b5b5b320SKhalil Blaiech }; 2226b5b5b320SKhalil Blaiech 2227b5b5b320SKhalil Blaiech MODULE_DEVICE_TABLE(acpi, mlxbf_i2c_acpi_ids); 2228b5b5b320SKhalil Blaiech 2229b5b5b320SKhalil Blaiech static int mlxbf_i2c_acpi_probe(struct device *dev, struct mlxbf_i2c_priv *priv) 2230b5b5b320SKhalil Blaiech { 2231b5b5b320SKhalil Blaiech const struct acpi_device_id *aid; 2232b5b5b320SKhalil Blaiech struct acpi_device *adev; 2233b5b5b320SKhalil Blaiech unsigned long bus_id = 0; 2234b5b5b320SKhalil Blaiech const char *uid; 2235b5b5b320SKhalil Blaiech int ret; 2236b5b5b320SKhalil Blaiech 2237b5b5b320SKhalil Blaiech if (acpi_disabled) 2238b5b5b320SKhalil Blaiech return -ENOENT; 2239b5b5b320SKhalil Blaiech 2240b5b5b320SKhalil Blaiech adev = ACPI_COMPANION(dev); 2241b5b5b320SKhalil Blaiech if (!adev) 2242b5b5b320SKhalil Blaiech return -ENXIO; 2243b5b5b320SKhalil Blaiech 2244b5b5b320SKhalil Blaiech aid = acpi_match_device(mlxbf_i2c_acpi_ids, dev); 2245b5b5b320SKhalil Blaiech if (!aid) 2246b5b5b320SKhalil Blaiech return -ENODEV; 2247b5b5b320SKhalil Blaiech 2248b5b5b320SKhalil Blaiech priv->chip = (struct mlxbf_i2c_chip_info *)aid->driver_data; 2249b5b5b320SKhalil Blaiech 2250b5b5b320SKhalil Blaiech uid = acpi_device_uid(adev); 2251b5b5b320SKhalil Blaiech if (!uid || !(*uid)) { 2252b5b5b320SKhalil Blaiech dev_err(dev, "Cannot retrieve UID\n"); 2253b5b5b320SKhalil Blaiech return -ENODEV; 2254b5b5b320SKhalil Blaiech } 2255b5b5b320SKhalil Blaiech 2256b5b5b320SKhalil Blaiech ret = kstrtoul(uid, 0, &bus_id); 2257b5b5b320SKhalil Blaiech if (!ret) 2258b5b5b320SKhalil Blaiech priv->bus = bus_id; 2259b5b5b320SKhalil Blaiech 2260b5b5b320SKhalil Blaiech return ret; 2261b5b5b320SKhalil Blaiech } 2262ed01ddc6SKhalil Blaiech #else 2263ed01ddc6SKhalil Blaiech static int mlxbf_i2c_acpi_probe(struct device *dev, struct mlxbf_i2c_priv *priv) 2264ed01ddc6SKhalil Blaiech { 2265ed01ddc6SKhalil Blaiech return -ENOENT; 2266ed01ddc6SKhalil Blaiech } 2267ed01ddc6SKhalil Blaiech #endif /* CONFIG_ACPI */ 2268b5b5b320SKhalil Blaiech 2269b5b5b320SKhalil Blaiech static int mlxbf_i2c_of_probe(struct device *dev, struct mlxbf_i2c_priv *priv) 2270b5b5b320SKhalil Blaiech { 2271b5b5b320SKhalil Blaiech const struct of_device_id *oid; 2272b5b5b320SKhalil Blaiech int bus_id = -1; 2273b5b5b320SKhalil Blaiech 2274b5b5b320SKhalil Blaiech if (IS_ENABLED(CONFIG_OF) && dev->of_node) { 2275b5b5b320SKhalil Blaiech oid = of_match_node(mlxbf_i2c_dt_ids, dev->of_node); 2276b5b5b320SKhalil Blaiech if (!oid) 2277b5b5b320SKhalil Blaiech return -ENODEV; 2278b5b5b320SKhalil Blaiech 2279b5b5b320SKhalil Blaiech priv->chip = oid->data; 2280b5b5b320SKhalil Blaiech 2281b5b5b320SKhalil Blaiech bus_id = of_alias_get_id(dev->of_node, "i2c"); 2282b5b5b320SKhalil Blaiech if (bus_id >= 0) 2283b5b5b320SKhalil Blaiech priv->bus = bus_id; 2284b5b5b320SKhalil Blaiech } 2285b5b5b320SKhalil Blaiech 2286b5b5b320SKhalil Blaiech if (bus_id < 0) { 2287b5b5b320SKhalil Blaiech dev_err(dev, "Cannot get bus id"); 2288b5b5b320SKhalil Blaiech return bus_id; 2289b5b5b320SKhalil Blaiech } 2290b5b5b320SKhalil Blaiech 2291b5b5b320SKhalil Blaiech return 0; 2292b5b5b320SKhalil Blaiech } 2293b5b5b320SKhalil Blaiech 2294b5b5b320SKhalil Blaiech static int mlxbf_i2c_probe(struct platform_device *pdev) 2295b5b5b320SKhalil Blaiech { 2296b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 2297b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv; 2298b5b5b320SKhalil Blaiech struct i2c_adapter *adap; 2299b5b5b320SKhalil Blaiech int irq, ret; 2300b5b5b320SKhalil Blaiech 2301b5b5b320SKhalil Blaiech priv = devm_kzalloc(dev, sizeof(struct mlxbf_i2c_priv), GFP_KERNEL); 2302b5b5b320SKhalil Blaiech if (!priv) 2303b5b5b320SKhalil Blaiech return -ENOMEM; 2304b5b5b320SKhalil Blaiech 2305b5b5b320SKhalil Blaiech ret = mlxbf_i2c_acpi_probe(dev, priv); 2306b5b5b320SKhalil Blaiech if (ret < 0 && ret != -ENOENT && ret != -ENXIO) 2307b5b5b320SKhalil Blaiech ret = mlxbf_i2c_of_probe(dev, priv); 2308b5b5b320SKhalil Blaiech 2309b5b5b320SKhalil Blaiech if (ret < 0) 2310b5b5b320SKhalil Blaiech return ret; 2311b5b5b320SKhalil Blaiech 2312b5b5b320SKhalil Blaiech ret = mlxbf_i2c_init_resource(pdev, &priv->smbus, 2313b5b5b320SKhalil Blaiech MLXBF_I2C_SMBUS_RES); 2314b5b5b320SKhalil Blaiech if (ret < 0) { 2315b5b5b320SKhalil Blaiech dev_err(dev, "Cannot fetch smbus resource info"); 2316b5b5b320SKhalil Blaiech return ret; 2317b5b5b320SKhalil Blaiech } 2318b5b5b320SKhalil Blaiech 2319b5b5b320SKhalil Blaiech ret = mlxbf_i2c_init_resource(pdev, &priv->mst_cause, 2320b5b5b320SKhalil Blaiech MLXBF_I2C_MST_CAUSE_RES); 2321b5b5b320SKhalil Blaiech if (ret < 0) { 2322b5b5b320SKhalil Blaiech dev_err(dev, "Cannot fetch cause master resource info"); 2323b5b5b320SKhalil Blaiech return ret; 2324b5b5b320SKhalil Blaiech } 2325b5b5b320SKhalil Blaiech 2326b5b5b320SKhalil Blaiech ret = mlxbf_i2c_init_resource(pdev, &priv->slv_cause, 2327b5b5b320SKhalil Blaiech MLXBF_I2C_SLV_CAUSE_RES); 2328b5b5b320SKhalil Blaiech if (ret < 0) { 2329b5b5b320SKhalil Blaiech dev_err(dev, "Cannot fetch cause slave resource info"); 2330b5b5b320SKhalil Blaiech return ret; 2331b5b5b320SKhalil Blaiech } 2332b5b5b320SKhalil Blaiech 2333b5b5b320SKhalil Blaiech adap = &priv->adap; 2334b5b5b320SKhalil Blaiech adap->owner = THIS_MODULE; 2335b5b5b320SKhalil Blaiech adap->class = I2C_CLASS_HWMON; 2336b5b5b320SKhalil Blaiech adap->algo = &mlxbf_i2c_algo; 2337b5b5b320SKhalil Blaiech adap->quirks = &mlxbf_i2c_quirks; 2338b5b5b320SKhalil Blaiech adap->dev.parent = dev; 2339b5b5b320SKhalil Blaiech adap->dev.of_node = dev->of_node; 2340b5b5b320SKhalil Blaiech adap->nr = priv->bus; 2341b5b5b320SKhalil Blaiech 2342b5b5b320SKhalil Blaiech snprintf(adap->name, sizeof(adap->name), "i2c%d", adap->nr); 2343b5b5b320SKhalil Blaiech i2c_set_adapdata(adap, priv); 2344b5b5b320SKhalil Blaiech 2345b5b5b320SKhalil Blaiech /* Read Core PLL frequency. */ 2346b5b5b320SKhalil Blaiech ret = mlxbf_i2c_calculate_corepll_freq(pdev, priv); 2347b5b5b320SKhalil Blaiech if (ret < 0) { 2348b5b5b320SKhalil Blaiech dev_err(dev, "cannot get core clock frequency\n"); 2349b5b5b320SKhalil Blaiech /* Set to default value. */ 2350b5b5b320SKhalil Blaiech priv->frequency = MLXBF_I2C_COREPLL_FREQ; 2351b5b5b320SKhalil Blaiech } 2352b5b5b320SKhalil Blaiech 2353b5b5b320SKhalil Blaiech /* 2354b5b5b320SKhalil Blaiech * Initialize master. 2355b5b5b320SKhalil Blaiech * Note that a physical bus might be shared among Linux and firmware 2356b5b5b320SKhalil Blaiech * (e.g., ATF). Thus, the bus should be initialized and ready and 2357b5b5b320SKhalil Blaiech * bus initialization would be unnecessary. This requires additional 2358b5b5b320SKhalil Blaiech * knowledge about physical busses. But, since an extra initialization 2359b5b5b320SKhalil Blaiech * does not really hurt, then keep the code as is. 2360b5b5b320SKhalil Blaiech */ 2361b5b5b320SKhalil Blaiech ret = mlxbf_i2c_init_master(pdev, priv); 2362b5b5b320SKhalil Blaiech if (ret < 0) { 2363b5b5b320SKhalil Blaiech dev_err(dev, "failed to initialize smbus master %d", 2364b5b5b320SKhalil Blaiech priv->bus); 2365b5b5b320SKhalil Blaiech return ret; 2366b5b5b320SKhalil Blaiech } 2367b5b5b320SKhalil Blaiech 2368b5b5b320SKhalil Blaiech mlxbf_i2c_init_timings(pdev, priv); 2369b5b5b320SKhalil Blaiech 2370b5b5b320SKhalil Blaiech mlxbf_i2c_init_slave(pdev, priv); 2371b5b5b320SKhalil Blaiech 2372b5b5b320SKhalil Blaiech irq = platform_get_irq(pdev, 0); 23730d3bf53eSSergey Shtylyov if (irq < 0) 23740d3bf53eSSergey Shtylyov return irq; 2375b5b5b320SKhalil Blaiech ret = devm_request_irq(dev, irq, mlxbf_smbus_irq, 2376b5b5b320SKhalil Blaiech IRQF_ONESHOT | IRQF_SHARED | IRQF_PROBE_SHARED, 2377b5b5b320SKhalil Blaiech dev_name(dev), priv); 2378b5b5b320SKhalil Blaiech if (ret < 0) { 2379b5b5b320SKhalil Blaiech dev_err(dev, "Cannot get irq %d\n", irq); 2380b5b5b320SKhalil Blaiech return ret; 2381b5b5b320SKhalil Blaiech } 2382b5b5b320SKhalil Blaiech 2383b5b5b320SKhalil Blaiech priv->irq = irq; 2384b5b5b320SKhalil Blaiech 2385b5b5b320SKhalil Blaiech platform_set_drvdata(pdev, priv); 2386b5b5b320SKhalil Blaiech 2387b5b5b320SKhalil Blaiech ret = i2c_add_numbered_adapter(adap); 2388b5b5b320SKhalil Blaiech if (ret < 0) 2389b5b5b320SKhalil Blaiech return ret; 2390b5b5b320SKhalil Blaiech 2391b5b5b320SKhalil Blaiech mutex_lock(&mlxbf_i2c_bus_lock); 2392b5b5b320SKhalil Blaiech mlxbf_i2c_bus_count++; 2393b5b5b320SKhalil Blaiech mutex_unlock(&mlxbf_i2c_bus_lock); 2394b5b5b320SKhalil Blaiech 2395b5b5b320SKhalil Blaiech return 0; 2396b5b5b320SKhalil Blaiech } 2397b5b5b320SKhalil Blaiech 2398b5b5b320SKhalil Blaiech static int mlxbf_i2c_remove(struct platform_device *pdev) 2399b5b5b320SKhalil Blaiech { 2400b5b5b320SKhalil Blaiech struct mlxbf_i2c_priv *priv = platform_get_drvdata(pdev); 2401b5b5b320SKhalil Blaiech struct device *dev = &pdev->dev; 2402b5b5b320SKhalil Blaiech struct resource *params; 2403b5b5b320SKhalil Blaiech 2404b5b5b320SKhalil Blaiech params = priv->smbus->params; 2405b5b5b320SKhalil Blaiech devm_release_mem_region(dev, params->start, resource_size(params)); 2406b5b5b320SKhalil Blaiech 2407b5b5b320SKhalil Blaiech params = priv->mst_cause->params; 2408b5b5b320SKhalil Blaiech devm_release_mem_region(dev, params->start, resource_size(params)); 2409b5b5b320SKhalil Blaiech 2410b5b5b320SKhalil Blaiech params = priv->slv_cause->params; 2411b5b5b320SKhalil Blaiech devm_release_mem_region(dev, params->start, resource_size(params)); 2412b5b5b320SKhalil Blaiech 2413b5b5b320SKhalil Blaiech /* 2414b5b5b320SKhalil Blaiech * Release shared resources. This should be done when releasing 2415b5b5b320SKhalil Blaiech * the I2C controller. 2416b5b5b320SKhalil Blaiech */ 2417b5b5b320SKhalil Blaiech mutex_lock(&mlxbf_i2c_bus_lock); 2418b5b5b320SKhalil Blaiech if (--mlxbf_i2c_bus_count == 0) { 2419b5b5b320SKhalil Blaiech mlxbf_i2c_release_coalesce(pdev, priv); 2420b5b5b320SKhalil Blaiech mlxbf_i2c_release_corepll(pdev, priv); 2421b5b5b320SKhalil Blaiech mlxbf_i2c_release_gpio(pdev, priv); 2422b5b5b320SKhalil Blaiech } 2423b5b5b320SKhalil Blaiech mutex_unlock(&mlxbf_i2c_bus_lock); 2424b5b5b320SKhalil Blaiech 2425b5b5b320SKhalil Blaiech devm_free_irq(dev, priv->irq, priv); 2426b5b5b320SKhalil Blaiech 2427b5b5b320SKhalil Blaiech i2c_del_adapter(&priv->adap); 2428b5b5b320SKhalil Blaiech 2429b5b5b320SKhalil Blaiech return 0; 2430b5b5b320SKhalil Blaiech } 2431b5b5b320SKhalil Blaiech 2432b5b5b320SKhalil Blaiech static struct platform_driver mlxbf_i2c_driver = { 2433b5b5b320SKhalil Blaiech .probe = mlxbf_i2c_probe, 2434b5b5b320SKhalil Blaiech .remove = mlxbf_i2c_remove, 2435b5b5b320SKhalil Blaiech .driver = { 2436b5b5b320SKhalil Blaiech .name = "i2c-mlxbf", 2437b5b5b320SKhalil Blaiech .of_match_table = mlxbf_i2c_dt_ids, 2438ed01ddc6SKhalil Blaiech #ifdef CONFIG_ACPI 2439b5b5b320SKhalil Blaiech .acpi_match_table = ACPI_PTR(mlxbf_i2c_acpi_ids), 2440ed01ddc6SKhalil Blaiech #endif /* CONFIG_ACPI */ 2441b5b5b320SKhalil Blaiech }, 2442b5b5b320SKhalil Blaiech }; 2443b5b5b320SKhalil Blaiech 2444b5b5b320SKhalil Blaiech static int __init mlxbf_i2c_init(void) 2445b5b5b320SKhalil Blaiech { 2446b5b5b320SKhalil Blaiech mutex_init(&mlxbf_i2c_coalesce_lock); 2447b5b5b320SKhalil Blaiech mutex_init(&mlxbf_i2c_corepll_lock); 2448b5b5b320SKhalil Blaiech mutex_init(&mlxbf_i2c_gpio_lock); 2449b5b5b320SKhalil Blaiech 2450b5b5b320SKhalil Blaiech mutex_init(&mlxbf_i2c_bus_lock); 2451b5b5b320SKhalil Blaiech 2452b5b5b320SKhalil Blaiech return platform_driver_register(&mlxbf_i2c_driver); 2453b5b5b320SKhalil Blaiech } 2454b5b5b320SKhalil Blaiech module_init(mlxbf_i2c_init); 2455b5b5b320SKhalil Blaiech 2456b5b5b320SKhalil Blaiech static void __exit mlxbf_i2c_exit(void) 2457b5b5b320SKhalil Blaiech { 2458b5b5b320SKhalil Blaiech platform_driver_unregister(&mlxbf_i2c_driver); 2459b5b5b320SKhalil Blaiech 2460b5b5b320SKhalil Blaiech mutex_destroy(&mlxbf_i2c_bus_lock); 2461b5b5b320SKhalil Blaiech 2462b5b5b320SKhalil Blaiech mutex_destroy(&mlxbf_i2c_gpio_lock); 2463b5b5b320SKhalil Blaiech mutex_destroy(&mlxbf_i2c_corepll_lock); 2464b5b5b320SKhalil Blaiech mutex_destroy(&mlxbf_i2c_coalesce_lock); 2465b5b5b320SKhalil Blaiech } 2466b5b5b320SKhalil Blaiech module_exit(mlxbf_i2c_exit); 2467b5b5b320SKhalil Blaiech 2468b5b5b320SKhalil Blaiech MODULE_DESCRIPTION("Mellanox BlueField I2C bus driver"); 246954b9c3d0SKhalil Blaiech MODULE_AUTHOR("Khalil Blaiech <kblaiech@nvidia.com>"); 2470b5b5b320SKhalil Blaiech MODULE_LICENSE("GPL v2"); 2471