162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Synopsys DesignWare I2C adapter driver. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Based on the TI DAVINCI I2C adapter driver. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 2006 Texas Instruments. 862306a36Sopenharmony_ci * Copyright (C) 2007 MontaVista Software Inc. 962306a36Sopenharmony_ci * Copyright (C) 2009 Provigent Ltd. 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/bits.h> 1362306a36Sopenharmony_ci#include <linux/compiler_types.h> 1462306a36Sopenharmony_ci#include <linux/completion.h> 1562306a36Sopenharmony_ci#include <linux/dev_printk.h> 1662306a36Sopenharmony_ci#include <linux/errno.h> 1762306a36Sopenharmony_ci#include <linux/i2c.h> 1862306a36Sopenharmony_ci#include <linux/regmap.h> 1962306a36Sopenharmony_ci#include <linux/types.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \ 2262306a36Sopenharmony_ci I2C_FUNC_SMBUS_BYTE | \ 2362306a36Sopenharmony_ci I2C_FUNC_SMBUS_BYTE_DATA | \ 2462306a36Sopenharmony_ci I2C_FUNC_SMBUS_WORD_DATA | \ 2562306a36Sopenharmony_ci I2C_FUNC_SMBUS_BLOCK_DATA | \ 2662306a36Sopenharmony_ci I2C_FUNC_SMBUS_I2C_BLOCK) 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define DW_IC_CON_MASTER BIT(0) 2962306a36Sopenharmony_ci#define DW_IC_CON_SPEED_STD (1 << 1) 3062306a36Sopenharmony_ci#define DW_IC_CON_SPEED_FAST (2 << 1) 3162306a36Sopenharmony_ci#define DW_IC_CON_SPEED_HIGH (3 << 1) 3262306a36Sopenharmony_ci#define DW_IC_CON_SPEED_MASK GENMASK(2, 1) 3362306a36Sopenharmony_ci#define DW_IC_CON_10BITADDR_SLAVE BIT(3) 3462306a36Sopenharmony_ci#define DW_IC_CON_10BITADDR_MASTER BIT(4) 3562306a36Sopenharmony_ci#define DW_IC_CON_RESTART_EN BIT(5) 3662306a36Sopenharmony_ci#define DW_IC_CON_SLAVE_DISABLE BIT(6) 3762306a36Sopenharmony_ci#define DW_IC_CON_STOP_DET_IFADDRESSED BIT(7) 3862306a36Sopenharmony_ci#define DW_IC_CON_TX_EMPTY_CTRL BIT(8) 3962306a36Sopenharmony_ci#define DW_IC_CON_RX_FIFO_FULL_HLD_CTRL BIT(9) 4062306a36Sopenharmony_ci#define DW_IC_CON_BUS_CLEAR_CTRL BIT(11) 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define DW_IC_DATA_CMD_DAT GENMASK(7, 0) 4362306a36Sopenharmony_ci#define DW_IC_DATA_CMD_FIRST_DATA_BYTE BIT(11) 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci/* 4662306a36Sopenharmony_ci * Registers offset 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_ci#define DW_IC_CON 0x00 4962306a36Sopenharmony_ci#define DW_IC_TAR 0x04 5062306a36Sopenharmony_ci#define DW_IC_SAR 0x08 5162306a36Sopenharmony_ci#define DW_IC_DATA_CMD 0x10 5262306a36Sopenharmony_ci#define DW_IC_SS_SCL_HCNT 0x14 5362306a36Sopenharmony_ci#define DW_IC_SS_SCL_LCNT 0x18 5462306a36Sopenharmony_ci#define DW_IC_FS_SCL_HCNT 0x1c 5562306a36Sopenharmony_ci#define DW_IC_FS_SCL_LCNT 0x20 5662306a36Sopenharmony_ci#define DW_IC_HS_SCL_HCNT 0x24 5762306a36Sopenharmony_ci#define DW_IC_HS_SCL_LCNT 0x28 5862306a36Sopenharmony_ci#define DW_IC_INTR_STAT 0x2c 5962306a36Sopenharmony_ci#define DW_IC_INTR_MASK 0x30 6062306a36Sopenharmony_ci#define DW_IC_RAW_INTR_STAT 0x34 6162306a36Sopenharmony_ci#define DW_IC_RX_TL 0x38 6262306a36Sopenharmony_ci#define DW_IC_TX_TL 0x3c 6362306a36Sopenharmony_ci#define DW_IC_CLR_INTR 0x40 6462306a36Sopenharmony_ci#define DW_IC_CLR_RX_UNDER 0x44 6562306a36Sopenharmony_ci#define DW_IC_CLR_RX_OVER 0x48 6662306a36Sopenharmony_ci#define DW_IC_CLR_TX_OVER 0x4c 6762306a36Sopenharmony_ci#define DW_IC_CLR_RD_REQ 0x50 6862306a36Sopenharmony_ci#define DW_IC_CLR_TX_ABRT 0x54 6962306a36Sopenharmony_ci#define DW_IC_CLR_RX_DONE 0x58 7062306a36Sopenharmony_ci#define DW_IC_CLR_ACTIVITY 0x5c 7162306a36Sopenharmony_ci#define DW_IC_CLR_STOP_DET 0x60 7262306a36Sopenharmony_ci#define DW_IC_CLR_START_DET 0x64 7362306a36Sopenharmony_ci#define DW_IC_CLR_GEN_CALL 0x68 7462306a36Sopenharmony_ci#define DW_IC_ENABLE 0x6c 7562306a36Sopenharmony_ci#define DW_IC_STATUS 0x70 7662306a36Sopenharmony_ci#define DW_IC_TXFLR 0x74 7762306a36Sopenharmony_ci#define DW_IC_RXFLR 0x78 7862306a36Sopenharmony_ci#define DW_IC_SDA_HOLD 0x7c 7962306a36Sopenharmony_ci#define DW_IC_TX_ABRT_SOURCE 0x80 8062306a36Sopenharmony_ci#define DW_IC_ENABLE_STATUS 0x9c 8162306a36Sopenharmony_ci#define DW_IC_CLR_RESTART_DET 0xa8 8262306a36Sopenharmony_ci#define DW_IC_COMP_PARAM_1 0xf4 8362306a36Sopenharmony_ci#define DW_IC_COMP_VERSION 0xf8 8462306a36Sopenharmony_ci#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A /* "111*" == v1.11* */ 8562306a36Sopenharmony_ci#define DW_IC_COMP_TYPE 0xfc 8662306a36Sopenharmony_ci#define DW_IC_COMP_TYPE_VALUE 0x44570140 /* "DW" + 0x0140 */ 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci#define DW_IC_INTR_RX_UNDER BIT(0) 8962306a36Sopenharmony_ci#define DW_IC_INTR_RX_OVER BIT(1) 9062306a36Sopenharmony_ci#define DW_IC_INTR_RX_FULL BIT(2) 9162306a36Sopenharmony_ci#define DW_IC_INTR_TX_OVER BIT(3) 9262306a36Sopenharmony_ci#define DW_IC_INTR_TX_EMPTY BIT(4) 9362306a36Sopenharmony_ci#define DW_IC_INTR_RD_REQ BIT(5) 9462306a36Sopenharmony_ci#define DW_IC_INTR_TX_ABRT BIT(6) 9562306a36Sopenharmony_ci#define DW_IC_INTR_RX_DONE BIT(7) 9662306a36Sopenharmony_ci#define DW_IC_INTR_ACTIVITY BIT(8) 9762306a36Sopenharmony_ci#define DW_IC_INTR_STOP_DET BIT(9) 9862306a36Sopenharmony_ci#define DW_IC_INTR_START_DET BIT(10) 9962306a36Sopenharmony_ci#define DW_IC_INTR_GEN_CALL BIT(11) 10062306a36Sopenharmony_ci#define DW_IC_INTR_RESTART_DET BIT(12) 10162306a36Sopenharmony_ci#define DW_IC_INTR_MST_ON_HOLD BIT(13) 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ 10462306a36Sopenharmony_ci DW_IC_INTR_TX_ABRT | \ 10562306a36Sopenharmony_ci DW_IC_INTR_STOP_DET) 10662306a36Sopenharmony_ci#define DW_IC_INTR_MASTER_MASK (DW_IC_INTR_DEFAULT_MASK | \ 10762306a36Sopenharmony_ci DW_IC_INTR_TX_EMPTY) 10862306a36Sopenharmony_ci#define DW_IC_INTR_SLAVE_MASK (DW_IC_INTR_DEFAULT_MASK | \ 10962306a36Sopenharmony_ci DW_IC_INTR_RX_UNDER | \ 11062306a36Sopenharmony_ci DW_IC_INTR_RD_REQ) 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci#define DW_IC_ENABLE_ABORT BIT(1) 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#define DW_IC_STATUS_ACTIVITY BIT(0) 11562306a36Sopenharmony_ci#define DW_IC_STATUS_TFE BIT(2) 11662306a36Sopenharmony_ci#define DW_IC_STATUS_RFNE BIT(3) 11762306a36Sopenharmony_ci#define DW_IC_STATUS_MASTER_ACTIVITY BIT(5) 11862306a36Sopenharmony_ci#define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6) 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci#define DW_IC_SDA_HOLD_RX_SHIFT 16 12162306a36Sopenharmony_ci#define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, 16) 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci#define DW_IC_ERR_TX_ABRT 0x1 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci#define DW_IC_TAR_10BITADDR_MASTER BIT(12) 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci#define DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH (BIT(2) | BIT(3)) 12862306a36Sopenharmony_ci#define DW_IC_COMP_PARAM_1_SPEED_MODE_MASK GENMASK(3, 2) 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci/* 13162306a36Sopenharmony_ci * Sofware status flags 13262306a36Sopenharmony_ci */ 13362306a36Sopenharmony_ci#define STATUS_ACTIVE BIT(0) 13462306a36Sopenharmony_ci#define STATUS_WRITE_IN_PROGRESS BIT(1) 13562306a36Sopenharmony_ci#define STATUS_READ_IN_PROGRESS BIT(2) 13662306a36Sopenharmony_ci#define STATUS_MASK GENMASK(2, 0) 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci/* 13962306a36Sopenharmony_ci * operation modes 14062306a36Sopenharmony_ci */ 14162306a36Sopenharmony_ci#define DW_IC_MASTER 0 14262306a36Sopenharmony_ci#define DW_IC_SLAVE 1 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci/* 14562306a36Sopenharmony_ci * Hardware abort codes from the DW_IC_TX_ABRT_SOURCE register 14662306a36Sopenharmony_ci * 14762306a36Sopenharmony_ci * Only expected abort codes are listed here 14862306a36Sopenharmony_ci * refer to the datasheet for the full list 14962306a36Sopenharmony_ci */ 15062306a36Sopenharmony_ci#define ABRT_7B_ADDR_NOACK 0 15162306a36Sopenharmony_ci#define ABRT_10ADDR1_NOACK 1 15262306a36Sopenharmony_ci#define ABRT_10ADDR2_NOACK 2 15362306a36Sopenharmony_ci#define ABRT_TXDATA_NOACK 3 15462306a36Sopenharmony_ci#define ABRT_GCALL_NOACK 4 15562306a36Sopenharmony_ci#define ABRT_GCALL_READ 5 15662306a36Sopenharmony_ci#define ABRT_SBYTE_ACKDET 7 15762306a36Sopenharmony_ci#define ABRT_SBYTE_NORSTRT 9 15862306a36Sopenharmony_ci#define ABRT_10B_RD_NORSTRT 10 15962306a36Sopenharmony_ci#define ABRT_MASTER_DIS 11 16062306a36Sopenharmony_ci#define ARB_LOST 12 16162306a36Sopenharmony_ci#define ABRT_SLAVE_FLUSH_TXFIFO 13 16262306a36Sopenharmony_ci#define ABRT_SLAVE_ARBLOST 14 16362306a36Sopenharmony_ci#define ABRT_SLAVE_RD_INTX 15 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci#define DW_IC_TX_ABRT_7B_ADDR_NOACK BIT(ABRT_7B_ADDR_NOACK) 16662306a36Sopenharmony_ci#define DW_IC_TX_ABRT_10ADDR1_NOACK BIT(ABRT_10ADDR1_NOACK) 16762306a36Sopenharmony_ci#define DW_IC_TX_ABRT_10ADDR2_NOACK BIT(ABRT_10ADDR2_NOACK) 16862306a36Sopenharmony_ci#define DW_IC_TX_ABRT_TXDATA_NOACK BIT(ABRT_TXDATA_NOACK) 16962306a36Sopenharmony_ci#define DW_IC_TX_ABRT_GCALL_NOACK BIT(ABRT_GCALL_NOACK) 17062306a36Sopenharmony_ci#define DW_IC_TX_ABRT_GCALL_READ BIT(ABRT_GCALL_READ) 17162306a36Sopenharmony_ci#define DW_IC_TX_ABRT_SBYTE_ACKDET BIT(ABRT_SBYTE_ACKDET) 17262306a36Sopenharmony_ci#define DW_IC_TX_ABRT_SBYTE_NORSTRT BIT(ABRT_SBYTE_NORSTRT) 17362306a36Sopenharmony_ci#define DW_IC_TX_ABRT_10B_RD_NORSTRT BIT(ABRT_10B_RD_NORSTRT) 17462306a36Sopenharmony_ci#define DW_IC_TX_ABRT_MASTER_DIS BIT(ABRT_MASTER_DIS) 17562306a36Sopenharmony_ci#define DW_IC_TX_ARB_LOST BIT(ARB_LOST) 17662306a36Sopenharmony_ci#define DW_IC_RX_ABRT_SLAVE_RD_INTX BIT(ABRT_SLAVE_RD_INTX) 17762306a36Sopenharmony_ci#define DW_IC_RX_ABRT_SLAVE_ARBLOST BIT(ABRT_SLAVE_ARBLOST) 17862306a36Sopenharmony_ci#define DW_IC_RX_ABRT_SLAVE_FLUSH_TXFIFO BIT(ABRT_SLAVE_FLUSH_TXFIFO) 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \ 18162306a36Sopenharmony_ci DW_IC_TX_ABRT_10ADDR1_NOACK | \ 18262306a36Sopenharmony_ci DW_IC_TX_ABRT_10ADDR2_NOACK | \ 18362306a36Sopenharmony_ci DW_IC_TX_ABRT_TXDATA_NOACK | \ 18462306a36Sopenharmony_ci DW_IC_TX_ABRT_GCALL_NOACK) 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cistruct clk; 18762306a36Sopenharmony_cistruct device; 18862306a36Sopenharmony_cistruct reset_control; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci/** 19162306a36Sopenharmony_ci * struct dw_i2c_dev - private i2c-designware data 19262306a36Sopenharmony_ci * @dev: driver model device node 19362306a36Sopenharmony_ci * @map: IO registers map 19462306a36Sopenharmony_ci * @sysmap: System controller registers map 19562306a36Sopenharmony_ci * @base: IO registers pointer 19662306a36Sopenharmony_ci * @ext: Extended IO registers pointer 19762306a36Sopenharmony_ci * @cmd_complete: tx completion indicator 19862306a36Sopenharmony_ci * @clk: input reference clock 19962306a36Sopenharmony_ci * @pclk: clock required to access the registers 20062306a36Sopenharmony_ci * @rst: optional reset for the controller 20162306a36Sopenharmony_ci * @slave: represent an I2C slave device 20262306a36Sopenharmony_ci * @get_clk_rate_khz: callback to retrieve IP specific bus speed 20362306a36Sopenharmony_ci * @cmd_err: run time hadware error code 20462306a36Sopenharmony_ci * @msgs: points to an array of messages currently being transferred 20562306a36Sopenharmony_ci * @msgs_num: the number of elements in msgs 20662306a36Sopenharmony_ci * @msg_write_idx: the element index of the current tx message in the msgs array 20762306a36Sopenharmony_ci * @tx_buf_len: the length of the current tx buffer 20862306a36Sopenharmony_ci * @tx_buf: the current tx buffer 20962306a36Sopenharmony_ci * @msg_read_idx: the element index of the current rx message in the msgs array 21062306a36Sopenharmony_ci * @rx_buf_len: the length of the current rx buffer 21162306a36Sopenharmony_ci * @rx_buf: the current rx buffer 21262306a36Sopenharmony_ci * @msg_err: error status of the current transfer 21362306a36Sopenharmony_ci * @status: i2c master status, one of STATUS_* 21462306a36Sopenharmony_ci * @abort_source: copy of the TX_ABRT_SOURCE register 21562306a36Sopenharmony_ci * @irq: interrupt number for the i2c master 21662306a36Sopenharmony_ci * @flags: platform specific flags like type of IO accessors or model 21762306a36Sopenharmony_ci * @adapter: i2c subsystem adapter node 21862306a36Sopenharmony_ci * @functionality: I2C_FUNC_* ORed bits to reflect what controller does support 21962306a36Sopenharmony_ci * @master_cfg: configuration for the master device 22062306a36Sopenharmony_ci * @slave_cfg: configuration for the slave device 22162306a36Sopenharmony_ci * @tx_fifo_depth: depth of the hardware tx fifo 22262306a36Sopenharmony_ci * @rx_fifo_depth: depth of the hardware rx fifo 22362306a36Sopenharmony_ci * @rx_outstanding: current master-rx elements in tx fifo 22462306a36Sopenharmony_ci * @timings: bus clock frequency, SDA hold and other timings 22562306a36Sopenharmony_ci * @sda_hold_time: SDA hold value 22662306a36Sopenharmony_ci * @ss_hcnt: standard speed HCNT value 22762306a36Sopenharmony_ci * @ss_lcnt: standard speed LCNT value 22862306a36Sopenharmony_ci * @fs_hcnt: fast speed HCNT value 22962306a36Sopenharmony_ci * @fs_lcnt: fast speed LCNT value 23062306a36Sopenharmony_ci * @fp_hcnt: fast plus HCNT value 23162306a36Sopenharmony_ci * @fp_lcnt: fast plus LCNT value 23262306a36Sopenharmony_ci * @hs_hcnt: high speed HCNT value 23362306a36Sopenharmony_ci * @hs_lcnt: high speed LCNT value 23462306a36Sopenharmony_ci * @acquire_lock: function to acquire a hardware lock on the bus 23562306a36Sopenharmony_ci * @release_lock: function to release a hardware lock on the bus 23662306a36Sopenharmony_ci * @semaphore_idx: Index of table with semaphore type attached to the bus. It's 23762306a36Sopenharmony_ci * -1 if there is no semaphore. 23862306a36Sopenharmony_ci * @shared_with_punit: true if this bus is shared with the SoCs PUNIT 23962306a36Sopenharmony_ci * @disable: function to disable the controller 24062306a36Sopenharmony_ci * @init: function to initialize the I2C hardware 24162306a36Sopenharmony_ci * @set_sda_hold_time: callback to retrieve IP specific SDA hold timing 24262306a36Sopenharmony_ci * @mode: operation mode - DW_IC_MASTER or DW_IC_SLAVE 24362306a36Sopenharmony_ci * @rinfo: I²C GPIO recovery information 24462306a36Sopenharmony_ci * 24562306a36Sopenharmony_ci * HCNT and LCNT parameters can be used if the platform knows more accurate 24662306a36Sopenharmony_ci * values than the one computed based only on the input clock frequency. 24762306a36Sopenharmony_ci * Leave them to be %0 if not used. 24862306a36Sopenharmony_ci */ 24962306a36Sopenharmony_cistruct dw_i2c_dev { 25062306a36Sopenharmony_ci struct device *dev; 25162306a36Sopenharmony_ci struct regmap *map; 25262306a36Sopenharmony_ci struct regmap *sysmap; 25362306a36Sopenharmony_ci void __iomem *base; 25462306a36Sopenharmony_ci void __iomem *ext; 25562306a36Sopenharmony_ci struct completion cmd_complete; 25662306a36Sopenharmony_ci struct clk *clk; 25762306a36Sopenharmony_ci struct clk *pclk; 25862306a36Sopenharmony_ci struct reset_control *rst; 25962306a36Sopenharmony_ci struct i2c_client *slave; 26062306a36Sopenharmony_ci u32 (*get_clk_rate_khz) (struct dw_i2c_dev *dev); 26162306a36Sopenharmony_ci int cmd_err; 26262306a36Sopenharmony_ci struct i2c_msg *msgs; 26362306a36Sopenharmony_ci int msgs_num; 26462306a36Sopenharmony_ci int msg_write_idx; 26562306a36Sopenharmony_ci u32 tx_buf_len; 26662306a36Sopenharmony_ci u8 *tx_buf; 26762306a36Sopenharmony_ci int msg_read_idx; 26862306a36Sopenharmony_ci u32 rx_buf_len; 26962306a36Sopenharmony_ci u8 *rx_buf; 27062306a36Sopenharmony_ci int msg_err; 27162306a36Sopenharmony_ci unsigned int status; 27262306a36Sopenharmony_ci unsigned int abort_source; 27362306a36Sopenharmony_ci int irq; 27462306a36Sopenharmony_ci u32 flags; 27562306a36Sopenharmony_ci struct i2c_adapter adapter; 27662306a36Sopenharmony_ci u32 functionality; 27762306a36Sopenharmony_ci u32 master_cfg; 27862306a36Sopenharmony_ci u32 slave_cfg; 27962306a36Sopenharmony_ci unsigned int tx_fifo_depth; 28062306a36Sopenharmony_ci unsigned int rx_fifo_depth; 28162306a36Sopenharmony_ci int rx_outstanding; 28262306a36Sopenharmony_ci struct i2c_timings timings; 28362306a36Sopenharmony_ci u32 sda_hold_time; 28462306a36Sopenharmony_ci u16 ss_hcnt; 28562306a36Sopenharmony_ci u16 ss_lcnt; 28662306a36Sopenharmony_ci u16 fs_hcnt; 28762306a36Sopenharmony_ci u16 fs_lcnt; 28862306a36Sopenharmony_ci u16 fp_hcnt; 28962306a36Sopenharmony_ci u16 fp_lcnt; 29062306a36Sopenharmony_ci u16 hs_hcnt; 29162306a36Sopenharmony_ci u16 hs_lcnt; 29262306a36Sopenharmony_ci int (*acquire_lock)(void); 29362306a36Sopenharmony_ci void (*release_lock)(void); 29462306a36Sopenharmony_ci int semaphore_idx; 29562306a36Sopenharmony_ci bool shared_with_punit; 29662306a36Sopenharmony_ci void (*disable)(struct dw_i2c_dev *dev); 29762306a36Sopenharmony_ci int (*init)(struct dw_i2c_dev *dev); 29862306a36Sopenharmony_ci int (*set_sda_hold_time)(struct dw_i2c_dev *dev); 29962306a36Sopenharmony_ci int mode; 30062306a36Sopenharmony_ci struct i2c_bus_recovery_info rinfo; 30162306a36Sopenharmony_ci}; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci#define ACCESS_INTR_MASK BIT(0) 30462306a36Sopenharmony_ci#define ACCESS_NO_IRQ_SUSPEND BIT(1) 30562306a36Sopenharmony_ci#define ARBITRATION_SEMAPHORE BIT(2) 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci#define MODEL_MSCC_OCELOT BIT(8) 30862306a36Sopenharmony_ci#define MODEL_BAIKAL_BT1 BIT(9) 30962306a36Sopenharmony_ci#define MODEL_AMD_NAVI_GPU BIT(10) 31062306a36Sopenharmony_ci#define MODEL_WANGXUN_SP BIT(11) 31162306a36Sopenharmony_ci#define MODEL_MASK GENMASK(11, 8) 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci/* 31462306a36Sopenharmony_ci * Enable UCSI interrupt by writing 0xd at register 31562306a36Sopenharmony_ci * offset 0x474 specified in hardware specification. 31662306a36Sopenharmony_ci */ 31762306a36Sopenharmony_ci#define AMD_UCSI_INTR_REG 0x474 31862306a36Sopenharmony_ci#define AMD_UCSI_INTR_EN 0xd 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci#define TXGBE_TX_FIFO_DEPTH 4 32162306a36Sopenharmony_ci#define TXGBE_RX_FIFO_DEPTH 0 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_cistruct i2c_dw_semaphore_callbacks { 32462306a36Sopenharmony_ci int (*probe)(struct dw_i2c_dev *dev); 32562306a36Sopenharmony_ci void (*remove)(struct dw_i2c_dev *dev); 32662306a36Sopenharmony_ci}; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ciint i2c_dw_init_regmap(struct dw_i2c_dev *dev); 32962306a36Sopenharmony_ciu32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset); 33062306a36Sopenharmony_ciu32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset); 33162306a36Sopenharmony_ciint i2c_dw_set_sda_hold(struct dw_i2c_dev *dev); 33262306a36Sopenharmony_ciu32 i2c_dw_clk_rate(struct dw_i2c_dev *dev); 33362306a36Sopenharmony_ciint i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare); 33462306a36Sopenharmony_ciint i2c_dw_acquire_lock(struct dw_i2c_dev *dev); 33562306a36Sopenharmony_civoid i2c_dw_release_lock(struct dw_i2c_dev *dev); 33662306a36Sopenharmony_ciint i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev); 33762306a36Sopenharmony_ciint i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev); 33862306a36Sopenharmony_ciint i2c_dw_set_fifo_size(struct dw_i2c_dev *dev); 33962306a36Sopenharmony_ciu32 i2c_dw_func(struct i2c_adapter *adap); 34062306a36Sopenharmony_civoid i2c_dw_disable(struct dw_i2c_dev *dev); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_cistatic inline void __i2c_dw_enable(struct dw_i2c_dev *dev) 34362306a36Sopenharmony_ci{ 34462306a36Sopenharmony_ci dev->status |= STATUS_ACTIVE; 34562306a36Sopenharmony_ci regmap_write(dev->map, DW_IC_ENABLE, 1); 34662306a36Sopenharmony_ci} 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_cistatic inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev) 34962306a36Sopenharmony_ci{ 35062306a36Sopenharmony_ci regmap_write(dev->map, DW_IC_ENABLE, 0); 35162306a36Sopenharmony_ci dev->status &= ~STATUS_ACTIVE; 35262306a36Sopenharmony_ci} 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_civoid __i2c_dw_disable(struct dw_i2c_dev *dev); 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ciextern void i2c_dw_configure_master(struct dw_i2c_dev *dev); 35762306a36Sopenharmony_ciextern int i2c_dw_probe_master(struct dw_i2c_dev *dev); 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_SLAVE) 36062306a36Sopenharmony_ciextern void i2c_dw_configure_slave(struct dw_i2c_dev *dev); 36162306a36Sopenharmony_ciextern int i2c_dw_probe_slave(struct dw_i2c_dev *dev); 36262306a36Sopenharmony_ci#else 36362306a36Sopenharmony_cistatic inline void i2c_dw_configure_slave(struct dw_i2c_dev *dev) { } 36462306a36Sopenharmony_cistatic inline int i2c_dw_probe_slave(struct dw_i2c_dev *dev) { return -EINVAL; } 36562306a36Sopenharmony_ci#endif 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_cistatic inline int i2c_dw_probe(struct dw_i2c_dev *dev) 36862306a36Sopenharmony_ci{ 36962306a36Sopenharmony_ci switch (dev->mode) { 37062306a36Sopenharmony_ci case DW_IC_SLAVE: 37162306a36Sopenharmony_ci return i2c_dw_probe_slave(dev); 37262306a36Sopenharmony_ci case DW_IC_MASTER: 37362306a36Sopenharmony_ci return i2c_dw_probe_master(dev); 37462306a36Sopenharmony_ci default: 37562306a36Sopenharmony_ci dev_err(dev->dev, "Wrong operation mode: %d\n", dev->mode); 37662306a36Sopenharmony_ci return -EINVAL; 37762306a36Sopenharmony_ci } 37862306a36Sopenharmony_ci} 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_cistatic inline void i2c_dw_configure(struct dw_i2c_dev *dev) 38162306a36Sopenharmony_ci{ 38262306a36Sopenharmony_ci if (i2c_detect_slave_mode(dev->dev)) 38362306a36Sopenharmony_ci i2c_dw_configure_slave(dev); 38462306a36Sopenharmony_ci else 38562306a36Sopenharmony_ci i2c_dw_configure_master(dev); 38662306a36Sopenharmony_ci} 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_BAYTRAIL) 38962306a36Sopenharmony_ciint i2c_dw_baytrail_probe_lock_support(struct dw_i2c_dev *dev); 39062306a36Sopenharmony_ci#endif 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_AMDPSP) 39362306a36Sopenharmony_ciint i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev); 39462306a36Sopenharmony_ci#endif 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ciint i2c_dw_validate_speed(struct dw_i2c_dev *dev); 39762306a36Sopenharmony_civoid i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev); 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_ACPI) 40062306a36Sopenharmony_ciint i2c_dw_acpi_configure(struct device *device); 40162306a36Sopenharmony_ci#else 40262306a36Sopenharmony_cistatic inline int i2c_dw_acpi_configure(struct device *device) { return -ENODEV; } 40362306a36Sopenharmony_ci#endif 404