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