xref: /linux/drivers/i2c/busses/i2c-npcm7xx.c (revision e365422cef1ca2c964e25d26536120aab17991e2)
156a1485bSTali Perry // SPDX-License-Identifier: GPL-2.0
256a1485bSTali Perry /*
356a1485bSTali Perry  * Nuvoton NPCM7xx I2C Controller driver
456a1485bSTali Perry  *
556a1485bSTali Perry  * Copyright (C) 2020 Nuvoton Technologies tali.perry@nuvoton.com
656a1485bSTali Perry  */
756a1485bSTali Perry #include <linux/bitfield.h>
856a1485bSTali Perry #include <linux/clk.h>
956a1485bSTali Perry #include <linux/debugfs.h>
1056a1485bSTali Perry #include <linux/errno.h>
1156a1485bSTali Perry #include <linux/i2c.h>
1256a1485bSTali Perry #include <linux/interrupt.h>
1356a1485bSTali Perry #include <linux/iopoll.h>
1456a1485bSTali Perry #include <linux/irq.h>
1556a1485bSTali Perry #include <linux/jiffies.h>
1656a1485bSTali Perry #include <linux/kernel.h>
1756a1485bSTali Perry #include <linux/mfd/syscon.h>
1856a1485bSTali Perry #include <linux/module.h>
1956a1485bSTali Perry #include <linux/of.h>
2056a1485bSTali Perry #include <linux/platform_device.h>
2156a1485bSTali Perry #include <linux/regmap.h>
2256a1485bSTali Perry 
2356a1485bSTali Perry enum i2c_mode {
2456a1485bSTali Perry 	I2C_MASTER,
2556a1485bSTali Perry 	I2C_SLAVE,
2656a1485bSTali Perry };
2756a1485bSTali Perry 
2856a1485bSTali Perry /*
2956a1485bSTali Perry  * External I2C Interface driver xfer indication values, which indicate status
3056a1485bSTali Perry  * of the bus.
3156a1485bSTali Perry  */
3256a1485bSTali Perry enum i2c_state_ind {
3356a1485bSTali Perry 	I2C_NO_STATUS_IND = 0,
3456a1485bSTali Perry 	I2C_SLAVE_RCV_IND,
3556a1485bSTali Perry 	I2C_SLAVE_XMIT_IND,
3656a1485bSTali Perry 	I2C_SLAVE_XMIT_MISSING_DATA_IND,
3756a1485bSTali Perry 	I2C_SLAVE_RESTART_IND,
3856a1485bSTali Perry 	I2C_SLAVE_DONE_IND,
3956a1485bSTali Perry 	I2C_MASTER_DONE_IND,
4056a1485bSTali Perry 	I2C_NACK_IND,
4156a1485bSTali Perry 	I2C_BUS_ERR_IND,
4256a1485bSTali Perry 	I2C_WAKE_UP_IND,
4356a1485bSTali Perry 	I2C_BLOCK_BYTES_ERR_IND,
4456a1485bSTali Perry 	I2C_SLAVE_RCV_MISSING_DATA_IND,
4556a1485bSTali Perry };
4656a1485bSTali Perry 
4756a1485bSTali Perry /*
4856a1485bSTali Perry  * Operation type values (used to define the operation currently running)
4956a1485bSTali Perry  * module is interrupt driven, on each interrupt the current operation is
5056a1485bSTali Perry  * checked to see if the module is currently reading or writing.
5156a1485bSTali Perry  */
5256a1485bSTali Perry enum i2c_oper {
5356a1485bSTali Perry 	I2C_NO_OPER = 0,
5456a1485bSTali Perry 	I2C_WRITE_OPER,
5556a1485bSTali Perry 	I2C_READ_OPER,
5656a1485bSTali Perry };
5756a1485bSTali Perry 
5856a1485bSTali Perry /* I2C Bank (module had 2 banks of registers) */
5956a1485bSTali Perry enum i2c_bank {
6056a1485bSTali Perry 	I2C_BANK_0 = 0,
6156a1485bSTali Perry 	I2C_BANK_1,
6256a1485bSTali Perry };
6356a1485bSTali Perry 
6456a1485bSTali Perry /* Internal I2C states values (for the I2C module state machine). */
6556a1485bSTali Perry enum i2c_state {
6656a1485bSTali Perry 	I2C_DISABLE = 0,
6756a1485bSTali Perry 	I2C_IDLE,
6856a1485bSTali Perry 	I2C_MASTER_START,
6956a1485bSTali Perry 	I2C_SLAVE_MATCH,
7056a1485bSTali Perry 	I2C_OPER_STARTED,
7156a1485bSTali Perry 	I2C_STOP_PENDING,
7256a1485bSTali Perry };
7356a1485bSTali Perry 
74f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
75f5473692STali Perry /* Module supports setting multiple own slave addresses */
76f5473692STali Perry enum i2c_addr {
77f5473692STali Perry 	I2C_SLAVE_ADDR1 = 0,
78f5473692STali Perry 	I2C_SLAVE_ADDR2,
79f5473692STali Perry 	I2C_SLAVE_ADDR3,
80f5473692STali Perry 	I2C_SLAVE_ADDR4,
81f5473692STali Perry 	I2C_SLAVE_ADDR5,
82f5473692STali Perry 	I2C_SLAVE_ADDR6,
83f5473692STali Perry 	I2C_SLAVE_ADDR7,
84f5473692STali Perry 	I2C_SLAVE_ADDR8,
85f5473692STali Perry 	I2C_SLAVE_ADDR9,
86f5473692STali Perry 	I2C_SLAVE_ADDR10,
87f5473692STali Perry 	I2C_GC_ADDR,
88f5473692STali Perry 	I2C_ARP_ADDR,
89f5473692STali Perry };
90f5473692STali Perry #endif
91f5473692STali Perry 
9256a1485bSTali Perry /* init register and default value required to enable module */
9356a1485bSTali Perry #define NPCM_I2CSEGCTL			0xE4
9456a1485bSTali Perry 
9556a1485bSTali Perry /* Common regs */
9656a1485bSTali Perry #define NPCM_I2CSDA			0x00
9756a1485bSTali Perry #define NPCM_I2CST			0x02
9856a1485bSTali Perry #define NPCM_I2CCST			0x04
9956a1485bSTali Perry #define NPCM_I2CCTL1			0x06
10056a1485bSTali Perry #define NPCM_I2CADDR1			0x08
10156a1485bSTali Perry #define NPCM_I2CCTL2			0x0A
10256a1485bSTali Perry #define NPCM_I2CADDR2			0x0C
10356a1485bSTali Perry #define NPCM_I2CCTL3			0x0E
10456a1485bSTali Perry #define NPCM_I2CCST2			0x18
10556a1485bSTali Perry #define NPCM_I2CCST3			0x19
10656a1485bSTali Perry #define I2C_VER				0x1F
10756a1485bSTali Perry 
10856a1485bSTali Perry /* BANK 0 regs */
10956a1485bSTali Perry #define NPCM_I2CADDR3			0x10
11056a1485bSTali Perry #define NPCM_I2CADDR7			0x11
11156a1485bSTali Perry #define NPCM_I2CADDR4			0x12
11256a1485bSTali Perry #define NPCM_I2CADDR8			0x13
11356a1485bSTali Perry #define NPCM_I2CADDR5			0x14
11456a1485bSTali Perry #define NPCM_I2CADDR9			0x15
11556a1485bSTali Perry #define NPCM_I2CADDR6			0x16
11656a1485bSTali Perry #define NPCM_I2CADDR10			0x17
117a826b6e9SJonathan Neuschäfer #define NPCM_I2CCTL4			0x1A
118a826b6e9SJonathan Neuschäfer #define NPCM_I2CCTL5			0x1B
119a826b6e9SJonathan Neuschäfer #define NPCM_I2CSCLLT			0x1C /* SCL Low Time */
120a826b6e9SJonathan Neuschäfer #define NPCM_I2CFIF_CTL			0x1D /* FIFO Control */
121a826b6e9SJonathan Neuschäfer #define NPCM_I2CSCLHT			0x1E /* SCL High Time */
122a826b6e9SJonathan Neuschäfer 
123a826b6e9SJonathan Neuschäfer /* BANK 1 regs */
124a826b6e9SJonathan Neuschäfer #define NPCM_I2CFIF_CTS			0x10 /* Both FIFOs Control and Status */
125a826b6e9SJonathan Neuschäfer #define NPCM_I2CTXF_CTL			0x12 /* Tx-FIFO Control */
126a826b6e9SJonathan Neuschäfer #define NPCM_I2CT_OUT			0x14 /* Bus T.O. */
127a826b6e9SJonathan Neuschäfer #define NPCM_I2CPEC			0x16 /* PEC Data */
128a826b6e9SJonathan Neuschäfer #define NPCM_I2CTXF_STS			0x1A /* Tx-FIFO Status */
129a826b6e9SJonathan Neuschäfer #define NPCM_I2CRXF_STS			0x1C /* Rx-FIFO Status */
130a826b6e9SJonathan Neuschäfer #define NPCM_I2CRXF_CTL			0x1E /* Rx-FIFO Control */
13156a1485bSTali Perry 
132f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
133f5473692STali Perry /*
134f5473692STali Perry  * npcm_i2caddr array:
135f5473692STali Perry  * The module supports having multiple own slave addresses.
136f5473692STali Perry  * Since the addr regs are sprinkled all over the address space,
137f5473692STali Perry  * use this array to get the address or each register.
138f5473692STali Perry  */
1398f65c455STyrone Ting #define I2C_NUM_OWN_ADDR 10
14047d506d1STali Perry #define I2C_NUM_OWN_ADDR_SUPPORTED 2
14147d506d1STali Perry 
142e6197c82Skernel test robot static const int npcm_i2caddr[I2C_NUM_OWN_ADDR] = {
1438f65c455STyrone Ting 	NPCM_I2CADDR1, NPCM_I2CADDR2, NPCM_I2CADDR3, NPCM_I2CADDR4,
1448f65c455STyrone Ting 	NPCM_I2CADDR5, NPCM_I2CADDR6, NPCM_I2CADDR7, NPCM_I2CADDR8,
1458f65c455STyrone Ting 	NPCM_I2CADDR9, NPCM_I2CADDR10,
146f5473692STali Perry };
147f5473692STali Perry #endif
148f5473692STali Perry 
14956a1485bSTali Perry /* NPCM_I2CST reg fields */
1503ca8217dSJonathan Neuschäfer #define NPCM_I2CST_XMIT			BIT(0)	/* Transmit mode */
1513ca8217dSJonathan Neuschäfer #define NPCM_I2CST_MASTER		BIT(1)	/* Master mode */
1523ca8217dSJonathan Neuschäfer #define NPCM_I2CST_NMATCH		BIT(2)	/* New match */
1533ca8217dSJonathan Neuschäfer #define NPCM_I2CST_STASTR		BIT(3)	/* Stall after start */
1543ca8217dSJonathan Neuschäfer #define NPCM_I2CST_NEGACK		BIT(4)	/* Negative ACK */
1553ca8217dSJonathan Neuschäfer #define NPCM_I2CST_BER			BIT(5)	/* Bus error */
1563ca8217dSJonathan Neuschäfer #define NPCM_I2CST_SDAST		BIT(6)	/* SDA status */
1573ca8217dSJonathan Neuschäfer #define NPCM_I2CST_SLVSTP		BIT(7)	/* Slave stop */
15856a1485bSTali Perry 
15956a1485bSTali Perry /* NPCM_I2CCST reg fields */
1603ca8217dSJonathan Neuschäfer #define NPCM_I2CCST_BUSY		BIT(0)	/* Busy */
1613ca8217dSJonathan Neuschäfer #define NPCM_I2CCST_BB			BIT(1)	/* Bus busy */
1623ca8217dSJonathan Neuschäfer #define NPCM_I2CCST_MATCH		BIT(2)	/* Address match */
1633ca8217dSJonathan Neuschäfer #define NPCM_I2CCST_GCMATCH		BIT(3)	/* Global call match */
1643ca8217dSJonathan Neuschäfer #define NPCM_I2CCST_TSDA		BIT(4)	/* Test SDA line */
1653ca8217dSJonathan Neuschäfer #define NPCM_I2CCST_TGSCL		BIT(5)	/* Toggle SCL line */
1663ca8217dSJonathan Neuschäfer #define NPCM_I2CCST_MATCHAF		BIT(6)	/* Match address field */
1673ca8217dSJonathan Neuschäfer #define NPCM_I2CCST_ARPMATCH		BIT(7)	/* ARP address match */
16856a1485bSTali Perry 
16956a1485bSTali Perry /* NPCM_I2CCTL1 reg fields */
1703ca8217dSJonathan Neuschäfer #define NPCM_I2CCTL1_START		BIT(0)	/* Generate start condition */
1713ca8217dSJonathan Neuschäfer #define NPCM_I2CCTL1_STOP		BIT(1)	/* Generate stop condition */
1723ca8217dSJonathan Neuschäfer #define NPCM_I2CCTL1_INTEN		BIT(2)	/* Interrupt enable */
17356a1485bSTali Perry #define NPCM_I2CCTL1_EOBINTE		BIT(3)
17456a1485bSTali Perry #define NPCM_I2CCTL1_ACK		BIT(4)
1753ca8217dSJonathan Neuschäfer #define NPCM_I2CCTL1_GCMEN		BIT(5)	/* Global call match enable */
1763ca8217dSJonathan Neuschäfer #define NPCM_I2CCTL1_NMINTE		BIT(6)	/* New match interrupt enable */
1773ca8217dSJonathan Neuschäfer #define NPCM_I2CCTL1_STASTRE		BIT(7)	/* Stall after start enable */
17856a1485bSTali Perry 
17956a1485bSTali Perry /* RW1S fields (inside a RW reg): */
18056a1485bSTali Perry #define NPCM_I2CCTL1_RWS   \
18156a1485bSTali Perry 	(NPCM_I2CCTL1_START | NPCM_I2CCTL1_STOP | NPCM_I2CCTL1_ACK)
18256a1485bSTali Perry 
18356a1485bSTali Perry /* npcm_i2caddr reg fields */
1843ca8217dSJonathan Neuschäfer #define NPCM_I2CADDR_A			GENMASK(6, 0)	/* Address */
1853ca8217dSJonathan Neuschäfer #define NPCM_I2CADDR_SAEN		BIT(7)		/* Slave address enable */
18656a1485bSTali Perry 
18756a1485bSTali Perry /* NPCM_I2CCTL2 reg fields */
1883ca8217dSJonathan Neuschäfer #define I2CCTL2_ENABLE			BIT(0)		/* Module enable */
1893ca8217dSJonathan Neuschäfer #define I2CCTL2_SCLFRQ6_0		GENMASK(7, 1)	/* Bits 0:6 of frequency divisor */
19056a1485bSTali Perry 
19156a1485bSTali Perry /* NPCM_I2CCTL3 reg fields */
1923ca8217dSJonathan Neuschäfer #define I2CCTL3_SCLFRQ8_7		GENMASK(1, 0)	/* Bits 7:8 of frequency divisor */
1933ca8217dSJonathan Neuschäfer #define I2CCTL3_ARPMEN			BIT(2)	/* ARP match enable */
19456a1485bSTali Perry #define I2CCTL3_IDL_START		BIT(3)
19556a1485bSTali Perry #define I2CCTL3_400K_MODE		BIT(4)
19656a1485bSTali Perry #define I2CCTL3_BNK_SEL			BIT(5)
19756a1485bSTali Perry #define I2CCTL3_SDA_LVL			BIT(6)
19856a1485bSTali Perry #define I2CCTL3_SCL_LVL			BIT(7)
19956a1485bSTali Perry 
20056a1485bSTali Perry /* NPCM_I2CCST2 reg fields */
20156a1485bSTali Perry #define NPCM_I2CCST2_MATCHA1F		BIT(0)
20256a1485bSTali Perry #define NPCM_I2CCST2_MATCHA2F		BIT(1)
20356a1485bSTali Perry #define NPCM_I2CCST2_MATCHA3F		BIT(2)
20456a1485bSTali Perry #define NPCM_I2CCST2_MATCHA4F		BIT(3)
20556a1485bSTali Perry #define NPCM_I2CCST2_MATCHA5F		BIT(4)
20656a1485bSTali Perry #define NPCM_I2CCST2_MATCHA6F		BIT(5)
20756a1485bSTali Perry #define NPCM_I2CCST2_MATCHA7F		BIT(5)
20856a1485bSTali Perry #define NPCM_I2CCST2_INTSTS		BIT(7)
20956a1485bSTali Perry 
21056a1485bSTali Perry /* NPCM_I2CCST3 reg fields */
21156a1485bSTali Perry #define NPCM_I2CCST3_MATCHA8F		BIT(0)
21256a1485bSTali Perry #define NPCM_I2CCST3_MATCHA9F		BIT(1)
21356a1485bSTali Perry #define NPCM_I2CCST3_MATCHA10F		BIT(2)
21456a1485bSTali Perry #define NPCM_I2CCST3_EO_BUSY		BIT(7)
21556a1485bSTali Perry 
21656a1485bSTali Perry /* NPCM_I2CCTL4 reg fields */
21756a1485bSTali Perry #define I2CCTL4_HLDT			GENMASK(5, 0)
21856a1485bSTali Perry #define I2CCTL4_LVL_WE			BIT(7)
21956a1485bSTali Perry 
22056a1485bSTali Perry /* NPCM_I2CCTL5 reg fields */
22156a1485bSTali Perry #define I2CCTL5_DBNCT			GENMASK(3, 0)
22256a1485bSTali Perry 
22356a1485bSTali Perry /* NPCM_I2CFIF_CTS reg fields */
22456a1485bSTali Perry #define NPCM_I2CFIF_CTS_RXF_TXE		BIT(1)
22556a1485bSTali Perry #define NPCM_I2CFIF_CTS_RFTE_IE		BIT(3)
22656a1485bSTali Perry #define NPCM_I2CFIF_CTS_CLR_FIFO	BIT(6)
22756a1485bSTali Perry #define NPCM_I2CFIF_CTS_SLVRSTR		BIT(7)
22856a1485bSTali Perry 
229bbc38ed5STyrone Ting /* NPCM_I2CTXF_CTL reg field */
23056a1485bSTali Perry #define NPCM_I2CTXF_CTL_THR_TXIE	BIT(6)
23156a1485bSTali Perry 
23256a1485bSTali Perry /* NPCM_I2CT_OUT reg fields */
23356a1485bSTali Perry #define NPCM_I2CT_OUT_TO_CKDIV		GENMASK(5, 0)
23456a1485bSTali Perry #define NPCM_I2CT_OUT_T_OUTIE		BIT(6)
23556a1485bSTali Perry #define NPCM_I2CT_OUT_T_OUTST		BIT(7)
23656a1485bSTali Perry 
23756a1485bSTali Perry /* NPCM_I2CTXF_STS reg fields */
23856a1485bSTali Perry #define NPCM_I2CTXF_STS_TX_THST		BIT(6)
23956a1485bSTali Perry 
24056a1485bSTali Perry /* NPCM_I2CRXF_STS reg fields */
24156a1485bSTali Perry #define NPCM_I2CRXF_STS_RX_THST		BIT(6)
24256a1485bSTali Perry 
24356a1485bSTali Perry /* NPCM_I2CFIF_CTL reg fields */
24456a1485bSTali Perry #define NPCM_I2CFIF_CTL_FIFO_EN		BIT(4)
24556a1485bSTali Perry 
24656a1485bSTali Perry /* NPCM_I2CRXF_CTL reg fields */
24756a1485bSTali Perry #define NPCM_I2CRXF_CTL_THR_RXIE	BIT(6)
24856a1485bSTali Perry 
249bbc38ed5STyrone Ting #define MAX_I2C_HW_FIFO_SIZE		32
25056a1485bSTali Perry 
25156a1485bSTali Perry /* I2C_VER reg fields */
25256a1485bSTali Perry #define I2C_VER_VERSION			GENMASK(6, 0)
25356a1485bSTali Perry #define I2C_VER_FIFO_EN			BIT(7)
25456a1485bSTali Perry 
25556a1485bSTali Perry /* stall/stuck timeout in us */
25656a1485bSTali Perry #define DEFAULT_STALL_COUNT		25
25756a1485bSTali Perry 
25856a1485bSTali Perry /* SCLFRQ field position */
25956a1485bSTali Perry #define SCLFRQ_0_TO_6			GENMASK(6, 0)
26056a1485bSTali Perry #define SCLFRQ_7_TO_8			GENMASK(8, 7)
26156a1485bSTali Perry 
26256a1485bSTali Perry /* supported clk settings. values in Hz. */
26356a1485bSTali Perry #define I2C_FREQ_MIN_HZ			10000
26456a1485bSTali Perry #define I2C_FREQ_MAX_HZ			I2C_MAX_FAST_MODE_PLUS_FREQ
26556a1485bSTali Perry 
266bbc38ed5STyrone Ting struct npcm_i2c_data {
267bbc38ed5STyrone Ting 	u8 fifo_size;
268bbc38ed5STyrone Ting 	u32 segctl_init_val;
269bbc38ed5STyrone Ting 	u8 txf_sts_tx_bytes;
270bbc38ed5STyrone Ting 	u8 rxf_sts_rx_bytes;
271bbc38ed5STyrone Ting 	u8 rxf_ctl_last_pec;
272bbc38ed5STyrone Ting };
273bbc38ed5STyrone Ting 
274bbc38ed5STyrone Ting static const struct npcm_i2c_data npxm7xx_i2c_data = {
275bbc38ed5STyrone Ting 	.fifo_size = 16,
276bbc38ed5STyrone Ting 	.segctl_init_val = 0x0333F000,
277bbc38ed5STyrone Ting 	.txf_sts_tx_bytes = GENMASK(4, 0),
278bbc38ed5STyrone Ting 	.rxf_sts_rx_bytes = GENMASK(4, 0),
279bbc38ed5STyrone Ting 	.rxf_ctl_last_pec = BIT(5),
280bbc38ed5STyrone Ting };
281bbc38ed5STyrone Ting 
282bbc38ed5STyrone Ting static const struct npcm_i2c_data npxm8xx_i2c_data = {
283bbc38ed5STyrone Ting 	.fifo_size = 32,
284bbc38ed5STyrone Ting 	.segctl_init_val = 0x9333F000,
285bbc38ed5STyrone Ting 	.txf_sts_tx_bytes = GENMASK(5, 0),
286bbc38ed5STyrone Ting 	.rxf_sts_rx_bytes = GENMASK(5, 0),
287bbc38ed5STyrone Ting 	.rxf_ctl_last_pec = BIT(7),
288bbc38ed5STyrone Ting };
289bbc38ed5STyrone Ting 
29056a1485bSTali Perry /* Status of one I2C module */
29156a1485bSTali Perry struct npcm_i2c {
29256a1485bSTali Perry 	struct i2c_adapter adap;
29356a1485bSTali Perry 	struct device *dev;
29456a1485bSTali Perry 	unsigned char __iomem *reg;
295bbc38ed5STyrone Ting 	const struct npcm_i2c_data *data;
29656a1485bSTali Perry 	spinlock_t lock;   /* IRQ synchronization */
29756a1485bSTali Perry 	struct completion cmd_complete;
29856a1485bSTali Perry 	int cmd_err;
29956a1485bSTali Perry 	struct i2c_msg *msgs;
30056a1485bSTali Perry 	int msgs_num;
30156a1485bSTali Perry 	int num;
30256a1485bSTali Perry 	u32 apb_clk;
30356a1485bSTali Perry 	struct i2c_bus_recovery_info rinfo;
30456a1485bSTali Perry 	enum i2c_state state;
30556a1485bSTali Perry 	enum i2c_oper operation;
30656a1485bSTali Perry 	enum i2c_mode master_or_slave;
30756a1485bSTali Perry 	enum i2c_state_ind stop_ind;
30856a1485bSTali Perry 	u8 dest_addr;
30956a1485bSTali Perry 	u8 *rd_buf;
31056a1485bSTali Perry 	u16 rd_size;
31156a1485bSTali Perry 	u16 rd_ind;
31256a1485bSTali Perry 	u8 *wr_buf;
31356a1485bSTali Perry 	u16 wr_size;
31456a1485bSTali Perry 	u16 wr_ind;
31556a1485bSTali Perry 	bool fifo_use;
31656a1485bSTali Perry 	u16 PEC_mask; /* PEC bit mask per slave address */
31756a1485bSTali Perry 	bool PEC_use;
31856a1485bSTali Perry 	bool read_block_use;
31956a1485bSTali Perry 	unsigned long int_time_stamp;
32056a1485bSTali Perry 	unsigned long bus_freq; /* in Hz */
321f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
322f5473692STali Perry 	u8 own_slave_addr;
323f5473692STali Perry 	struct i2c_client *slave;
324f5473692STali Perry 	int slv_rd_size;
325f5473692STali Perry 	int slv_rd_ind;
326f5473692STali Perry 	int slv_wr_size;
327f5473692STali Perry 	int slv_wr_ind;
328bbc38ed5STyrone Ting 	u8 slv_rd_buf[MAX_I2C_HW_FIFO_SIZE];
329bbc38ed5STyrone Ting 	u8 slv_wr_buf[MAX_I2C_HW_FIFO_SIZE];
330f5473692STali Perry #endif
33156a1485bSTali Perry 	u64 ber_cnt;
33256a1485bSTali Perry 	u64 rec_succ_cnt;
33356a1485bSTali Perry 	u64 rec_fail_cnt;
33456a1485bSTali Perry 	u64 nack_cnt;
33556a1485bSTali Perry 	u64 timeout_cnt;
3360bf58eb1STali Perry 	u64 tx_complete_cnt;
33756a1485bSTali Perry };
33856a1485bSTali Perry 
33956a1485bSTali Perry static inline void npcm_i2c_select_bank(struct npcm_i2c *bus,
34056a1485bSTali Perry 					enum i2c_bank bank)
34156a1485bSTali Perry {
34256a1485bSTali Perry 	u8 i2cctl3 = ioread8(bus->reg + NPCM_I2CCTL3);
34356a1485bSTali Perry 
34456a1485bSTali Perry 	if (bank == I2C_BANK_0)
34556a1485bSTali Perry 		i2cctl3 = i2cctl3 & ~I2CCTL3_BNK_SEL;
34656a1485bSTali Perry 	else
34756a1485bSTali Perry 		i2cctl3 = i2cctl3 | I2CCTL3_BNK_SEL;
34856a1485bSTali Perry 	iowrite8(i2cctl3, bus->reg + NPCM_I2CCTL3);
34956a1485bSTali Perry }
35056a1485bSTali Perry 
35156a1485bSTali Perry static void npcm_i2c_init_params(struct npcm_i2c *bus)
35256a1485bSTali Perry {
35356a1485bSTali Perry 	bus->stop_ind = I2C_NO_STATUS_IND;
35456a1485bSTali Perry 	bus->rd_size = 0;
35556a1485bSTali Perry 	bus->wr_size = 0;
35656a1485bSTali Perry 	bus->rd_ind = 0;
35756a1485bSTali Perry 	bus->wr_ind = 0;
35856a1485bSTali Perry 	bus->read_block_use = false;
35956a1485bSTali Perry 	bus->int_time_stamp = 0;
36056a1485bSTali Perry 	bus->PEC_use = false;
36156a1485bSTali Perry 	bus->PEC_mask = 0;
362f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
363f5473692STali Perry 	if (bus->slave)
364f5473692STali Perry 		bus->master_or_slave = I2C_SLAVE;
365f5473692STali Perry #endif
36656a1485bSTali Perry }
36756a1485bSTali Perry 
36856a1485bSTali Perry static inline void npcm_i2c_wr_byte(struct npcm_i2c *bus, u8 data)
36956a1485bSTali Perry {
37056a1485bSTali Perry 	iowrite8(data, bus->reg + NPCM_I2CSDA);
37156a1485bSTali Perry }
37256a1485bSTali Perry 
37356a1485bSTali Perry static inline u8 npcm_i2c_rd_byte(struct npcm_i2c *bus)
37456a1485bSTali Perry {
37556a1485bSTali Perry 	return ioread8(bus->reg + NPCM_I2CSDA);
37656a1485bSTali Perry }
37756a1485bSTali Perry 
37856a1485bSTali Perry static int npcm_i2c_get_SCL(struct i2c_adapter *_adap)
37956a1485bSTali Perry {
38056a1485bSTali Perry 	struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
38156a1485bSTali Perry 
382ea9f8426STyrone Ting 	return !!(I2CCTL3_SCL_LVL & ioread8(bus->reg + NPCM_I2CCTL3));
38356a1485bSTali Perry }
38456a1485bSTali Perry 
38556a1485bSTali Perry static int npcm_i2c_get_SDA(struct i2c_adapter *_adap)
38656a1485bSTali Perry {
38756a1485bSTali Perry 	struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
38856a1485bSTali Perry 
389ea9f8426STyrone Ting 	return !!(I2CCTL3_SDA_LVL & ioread8(bus->reg + NPCM_I2CCTL3));
39056a1485bSTali Perry }
39156a1485bSTali Perry 
39256a1485bSTali Perry static inline u16 npcm_i2c_get_index(struct npcm_i2c *bus)
39356a1485bSTali Perry {
39456a1485bSTali Perry 	if (bus->operation == I2C_READ_OPER)
39556a1485bSTali Perry 		return bus->rd_ind;
39656a1485bSTali Perry 	if (bus->operation == I2C_WRITE_OPER)
39756a1485bSTali Perry 		return bus->wr_ind;
39856a1485bSTali Perry 	return 0;
39956a1485bSTali Perry }
40056a1485bSTali Perry 
40156a1485bSTali Perry /* quick protocol (just address) */
40256a1485bSTali Perry static inline bool npcm_i2c_is_quick(struct npcm_i2c *bus)
40356a1485bSTali Perry {
40456a1485bSTali Perry 	return bus->wr_size == 0 && bus->rd_size == 0;
40556a1485bSTali Perry }
40656a1485bSTali Perry 
40756a1485bSTali Perry static void npcm_i2c_disable(struct npcm_i2c *bus)
40856a1485bSTali Perry {
40956a1485bSTali Perry 	u8 i2cctl2;
41056a1485bSTali Perry 
411f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
412f5473692STali Perry 	int i;
413f5473692STali Perry 
414f5473692STali Perry 	/* Slave addresses removal */
41547d506d1STali Perry 	for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR_SUPPORTED; i++)
416f5473692STali Perry 		iowrite8(0, bus->reg + npcm_i2caddr[i]);
417f5473692STali Perry 
418f5473692STali Perry #endif
41956a1485bSTali Perry 	/* Disable module */
42056a1485bSTali Perry 	i2cctl2 = ioread8(bus->reg + NPCM_I2CCTL2);
42156a1485bSTali Perry 	i2cctl2 = i2cctl2 & ~I2CCTL2_ENABLE;
42256a1485bSTali Perry 	iowrite8(i2cctl2, bus->reg + NPCM_I2CCTL2);
42356a1485bSTali Perry 
42456a1485bSTali Perry 	bus->state = I2C_DISABLE;
42556a1485bSTali Perry }
42656a1485bSTali Perry 
42756a1485bSTali Perry static void npcm_i2c_enable(struct npcm_i2c *bus)
42856a1485bSTali Perry {
42956a1485bSTali Perry 	u8 i2cctl2 = ioread8(bus->reg + NPCM_I2CCTL2);
43056a1485bSTali Perry 
43156a1485bSTali Perry 	i2cctl2 = i2cctl2 | I2CCTL2_ENABLE;
43256a1485bSTali Perry 	iowrite8(i2cctl2, bus->reg + NPCM_I2CCTL2);
43356a1485bSTali Perry 	bus->state = I2C_IDLE;
43456a1485bSTali Perry }
43556a1485bSTali Perry 
43656a1485bSTali Perry /* enable\disable end of busy (EOB) interrupts */
43756a1485bSTali Perry static inline void npcm_i2c_eob_int(struct npcm_i2c *bus, bool enable)
43856a1485bSTali Perry {
43956a1485bSTali Perry 	u8 val;
44056a1485bSTali Perry 
44156a1485bSTali Perry 	/* Clear EO_BUSY pending bit: */
44256a1485bSTali Perry 	val = ioread8(bus->reg + NPCM_I2CCST3);
44356a1485bSTali Perry 	val = val | NPCM_I2CCST3_EO_BUSY;
44456a1485bSTali Perry 	iowrite8(val, bus->reg + NPCM_I2CCST3);
44556a1485bSTali Perry 
44656a1485bSTali Perry 	val = ioread8(bus->reg + NPCM_I2CCTL1);
44756a1485bSTali Perry 	val &= ~NPCM_I2CCTL1_RWS;
44856a1485bSTali Perry 	if (enable)
44956a1485bSTali Perry 		val |= NPCM_I2CCTL1_EOBINTE;
45056a1485bSTali Perry 	else
45156a1485bSTali Perry 		val &= ~NPCM_I2CCTL1_EOBINTE;
45256a1485bSTali Perry 	iowrite8(val, bus->reg + NPCM_I2CCTL1);
45356a1485bSTali Perry }
45456a1485bSTali Perry 
45556a1485bSTali Perry static inline bool npcm_i2c_tx_fifo_empty(struct npcm_i2c *bus)
45656a1485bSTali Perry {
45756a1485bSTali Perry 	u8 tx_fifo_sts;
45856a1485bSTali Perry 
45956a1485bSTali Perry 	tx_fifo_sts = ioread8(bus->reg + NPCM_I2CTXF_STS);
46056a1485bSTali Perry 	/* check if TX FIFO is not empty */
461bbc38ed5STyrone Ting 	if ((tx_fifo_sts & bus->data->txf_sts_tx_bytes) == 0)
46256a1485bSTali Perry 		return false;
46356a1485bSTali Perry 
46456a1485bSTali Perry 	/* check if TX FIFO status bit is set: */
46556a1485bSTali Perry 	return !!FIELD_GET(NPCM_I2CTXF_STS_TX_THST, tx_fifo_sts);
46656a1485bSTali Perry }
46756a1485bSTali Perry 
46856a1485bSTali Perry static inline bool npcm_i2c_rx_fifo_full(struct npcm_i2c *bus)
46956a1485bSTali Perry {
47056a1485bSTali Perry 	u8 rx_fifo_sts;
47156a1485bSTali Perry 
47256a1485bSTali Perry 	rx_fifo_sts = ioread8(bus->reg + NPCM_I2CRXF_STS);
47356a1485bSTali Perry 	/* check if RX FIFO is not empty: */
474bbc38ed5STyrone Ting 	if ((rx_fifo_sts & bus->data->rxf_sts_rx_bytes) == 0)
47556a1485bSTali Perry 		return false;
47656a1485bSTali Perry 
47756a1485bSTali Perry 	/* check if rx fifo full status is set: */
47856a1485bSTali Perry 	return !!FIELD_GET(NPCM_I2CRXF_STS_RX_THST, rx_fifo_sts);
47956a1485bSTali Perry }
48056a1485bSTali Perry 
48156a1485bSTali Perry static inline void npcm_i2c_clear_fifo_int(struct npcm_i2c *bus)
48256a1485bSTali Perry {
48356a1485bSTali Perry 	u8 val;
48456a1485bSTali Perry 
48556a1485bSTali Perry 	val = ioread8(bus->reg + NPCM_I2CFIF_CTS);
48656a1485bSTali Perry 	val = (val & NPCM_I2CFIF_CTS_SLVRSTR) | NPCM_I2CFIF_CTS_RXF_TXE;
48756a1485bSTali Perry 	iowrite8(val, bus->reg + NPCM_I2CFIF_CTS);
48856a1485bSTali Perry }
48956a1485bSTali Perry 
49056a1485bSTali Perry static inline void npcm_i2c_clear_tx_fifo(struct npcm_i2c *bus)
49156a1485bSTali Perry {
49256a1485bSTali Perry 	u8 val;
49356a1485bSTali Perry 
49456a1485bSTali Perry 	val = ioread8(bus->reg + NPCM_I2CTXF_STS);
49556a1485bSTali Perry 	val = val | NPCM_I2CTXF_STS_TX_THST;
49656a1485bSTali Perry 	iowrite8(val, bus->reg + NPCM_I2CTXF_STS);
49756a1485bSTali Perry }
49856a1485bSTali Perry 
49956a1485bSTali Perry static inline void npcm_i2c_clear_rx_fifo(struct npcm_i2c *bus)
50056a1485bSTali Perry {
50156a1485bSTali Perry 	u8 val;
50256a1485bSTali Perry 
50356a1485bSTali Perry 	val = ioread8(bus->reg + NPCM_I2CRXF_STS);
50456a1485bSTali Perry 	val = val | NPCM_I2CRXF_STS_RX_THST;
50556a1485bSTali Perry 	iowrite8(val, bus->reg + NPCM_I2CRXF_STS);
50656a1485bSTali Perry }
50756a1485bSTali Perry 
50856a1485bSTali Perry static void npcm_i2c_int_enable(struct npcm_i2c *bus, bool enable)
50956a1485bSTali Perry {
51056a1485bSTali Perry 	u8 val;
51156a1485bSTali Perry 
51256a1485bSTali Perry 	val = ioread8(bus->reg + NPCM_I2CCTL1);
51356a1485bSTali Perry 	val &= ~NPCM_I2CCTL1_RWS;
51456a1485bSTali Perry 	if (enable)
51556a1485bSTali Perry 		val |= NPCM_I2CCTL1_INTEN;
51656a1485bSTali Perry 	else
51756a1485bSTali Perry 		val &= ~NPCM_I2CCTL1_INTEN;
51856a1485bSTali Perry 	iowrite8(val, bus->reg + NPCM_I2CCTL1);
51956a1485bSTali Perry }
52056a1485bSTali Perry 
52156a1485bSTali Perry static inline void npcm_i2c_master_start(struct npcm_i2c *bus)
52256a1485bSTali Perry {
52356a1485bSTali Perry 	u8 val;
52456a1485bSTali Perry 
52556a1485bSTali Perry 	val = ioread8(bus->reg + NPCM_I2CCTL1);
52656a1485bSTali Perry 	val &= ~(NPCM_I2CCTL1_STOP | NPCM_I2CCTL1_ACK);
52756a1485bSTali Perry 	val |= NPCM_I2CCTL1_START;
52856a1485bSTali Perry 	iowrite8(val, bus->reg + NPCM_I2CCTL1);
52956a1485bSTali Perry }
53056a1485bSTali Perry 
53156a1485bSTali Perry static inline void npcm_i2c_master_stop(struct npcm_i2c *bus)
53256a1485bSTali Perry {
53356a1485bSTali Perry 	u8 val;
53456a1485bSTali Perry 
53556a1485bSTali Perry 	/*
53656a1485bSTali Perry 	 * override HW issue: I2C may fail to supply stop condition in Master
53756a1485bSTali Perry 	 * Write operation.
53856a1485bSTali Perry 	 * Need to delay at least 5 us from the last int, before issueing a stop
53956a1485bSTali Perry 	 */
54056a1485bSTali Perry 	udelay(10); /* function called from interrupt, can't sleep */
54156a1485bSTali Perry 	val = ioread8(bus->reg + NPCM_I2CCTL1);
54256a1485bSTali Perry 	val &= ~(NPCM_I2CCTL1_START | NPCM_I2CCTL1_ACK);
54356a1485bSTali Perry 	val |= NPCM_I2CCTL1_STOP;
54456a1485bSTali Perry 	iowrite8(val, bus->reg + NPCM_I2CCTL1);
54556a1485bSTali Perry 
54656a1485bSTali Perry 	if (!bus->fifo_use)
54756a1485bSTali Perry 		return;
54856a1485bSTali Perry 
54956a1485bSTali Perry 	npcm_i2c_select_bank(bus, I2C_BANK_1);
55056a1485bSTali Perry 
55156a1485bSTali Perry 	if (bus->operation == I2C_READ_OPER)
55256a1485bSTali Perry 		npcm_i2c_clear_rx_fifo(bus);
55356a1485bSTali Perry 	else
55456a1485bSTali Perry 		npcm_i2c_clear_tx_fifo(bus);
55556a1485bSTali Perry 	npcm_i2c_clear_fifo_int(bus);
55656a1485bSTali Perry 	iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
55756a1485bSTali Perry }
55856a1485bSTali Perry 
55956a1485bSTali Perry static inline void npcm_i2c_stall_after_start(struct npcm_i2c *bus, bool stall)
56056a1485bSTali Perry {
56156a1485bSTali Perry 	u8 val;
56256a1485bSTali Perry 
56356a1485bSTali Perry 	val = ioread8(bus->reg + NPCM_I2CCTL1);
56456a1485bSTali Perry 	val &= ~NPCM_I2CCTL1_RWS;
56556a1485bSTali Perry 	if (stall)
56656a1485bSTali Perry 		val |= NPCM_I2CCTL1_STASTRE;
56756a1485bSTali Perry 	else
56856a1485bSTali Perry 		val &= ~NPCM_I2CCTL1_STASTRE;
56956a1485bSTali Perry 	iowrite8(val, bus->reg + NPCM_I2CCTL1);
57056a1485bSTali Perry }
57156a1485bSTali Perry 
57256a1485bSTali Perry static inline void npcm_i2c_nack(struct npcm_i2c *bus)
57356a1485bSTali Perry {
57456a1485bSTali Perry 	u8 val;
57556a1485bSTali Perry 
57656a1485bSTali Perry 	val = ioread8(bus->reg + NPCM_I2CCTL1);
57756a1485bSTali Perry 	val &= ~(NPCM_I2CCTL1_STOP | NPCM_I2CCTL1_START);
57856a1485bSTali Perry 	val |= NPCM_I2CCTL1_ACK;
57956a1485bSTali Perry 	iowrite8(val, bus->reg + NPCM_I2CCTL1);
58056a1485bSTali Perry }
58156a1485bSTali Perry 
582e5222d40STali Perry static inline void npcm_i2c_clear_master_status(struct npcm_i2c *bus)
583e5222d40STali Perry {
584e5222d40STali Perry 	u8 val;
585e5222d40STali Perry 
586e5222d40STali Perry 	/* Clear NEGACK, STASTR and BER bits */
587e5222d40STali Perry 	val = NPCM_I2CST_BER | NPCM_I2CST_NEGACK | NPCM_I2CST_STASTR;
588e5222d40STali Perry 	iowrite8(val, bus->reg + NPCM_I2CST);
589e5222d40STali Perry }
590e5222d40STali Perry 
591f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
592f5473692STali Perry static void npcm_i2c_slave_int_enable(struct npcm_i2c *bus, bool enable)
593f5473692STali Perry {
594f5473692STali Perry 	u8 i2cctl1;
595f5473692STali Perry 
596f5473692STali Perry 	/* enable interrupt on slave match: */
597f5473692STali Perry 	i2cctl1 = ioread8(bus->reg + NPCM_I2CCTL1);
598f5473692STali Perry 	i2cctl1 &= ~NPCM_I2CCTL1_RWS;
599f5473692STali Perry 	if (enable)
600f5473692STali Perry 		i2cctl1 |= NPCM_I2CCTL1_NMINTE;
601f5473692STali Perry 	else
602f5473692STali Perry 		i2cctl1 &= ~NPCM_I2CCTL1_NMINTE;
603f5473692STali Perry 	iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1);
604f5473692STali Perry }
605f5473692STali Perry 
606f5473692STali Perry static int npcm_i2c_slave_enable(struct npcm_i2c *bus, enum i2c_addr addr_type,
607f5473692STali Perry 				 u8 addr, bool enable)
608f5473692STali Perry {
609f5473692STali Perry 	u8 i2cctl1;
610f5473692STali Perry 	u8 i2cctl3;
611f5473692STali Perry 	u8 sa_reg;
612f5473692STali Perry 
613f5473692STali Perry 	sa_reg = (addr & 0x7F) | FIELD_PREP(NPCM_I2CADDR_SAEN, enable);
614f5473692STali Perry 	if (addr_type == I2C_GC_ADDR) {
615f5473692STali Perry 		i2cctl1 = ioread8(bus->reg + NPCM_I2CCTL1);
616f5473692STali Perry 		if (enable)
617f5473692STali Perry 			i2cctl1 |= NPCM_I2CCTL1_GCMEN;
618f5473692STali Perry 		else
619f5473692STali Perry 			i2cctl1 &= ~NPCM_I2CCTL1_GCMEN;
620f5473692STali Perry 		iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1);
621f5473692STali Perry 		return 0;
62247d506d1STali Perry 	} else if (addr_type == I2C_ARP_ADDR) {
623f5473692STali Perry 		i2cctl3 = ioread8(bus->reg + NPCM_I2CCTL3);
624f5473692STali Perry 		if (enable)
625f5473692STali Perry 			i2cctl3 |= I2CCTL3_ARPMEN;
626f5473692STali Perry 		else
627f5473692STali Perry 			i2cctl3 &= ~I2CCTL3_ARPMEN;
628f5473692STali Perry 		iowrite8(i2cctl3, bus->reg + NPCM_I2CCTL3);
629f5473692STali Perry 		return 0;
630f5473692STali Perry 	}
63147d506d1STali Perry 	if (addr_type > I2C_SLAVE_ADDR2 && addr_type <= I2C_SLAVE_ADDR10)
63247d506d1STali Perry 		dev_err(bus->dev, "try to enable more than 2 SA not supported\n");
63347d506d1STali Perry 
634f5473692STali Perry 	if (addr_type >= I2C_ARP_ADDR)
635f5473692STali Perry 		return -EFAULT;
63647d506d1STali Perry 
637f5473692STali Perry 	/* Set and enable the address */
638f5473692STali Perry 	iowrite8(sa_reg, bus->reg + npcm_i2caddr[addr_type]);
639f5473692STali Perry 	npcm_i2c_slave_int_enable(bus, enable);
64047d506d1STali Perry 
641f5473692STali Perry 	return 0;
642f5473692STali Perry }
643f5473692STali Perry #endif
644f5473692STali Perry 
64556a1485bSTali Perry static void npcm_i2c_reset(struct npcm_i2c *bus)
64656a1485bSTali Perry {
64756a1485bSTali Perry 	/*
64856a1485bSTali Perry 	 * Save I2CCTL1 relevant bits. It is being cleared when the module
64956a1485bSTali Perry 	 *  is disabled.
65056a1485bSTali Perry 	 */
65156a1485bSTali Perry 	u8 i2cctl1;
652f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
653f5473692STali Perry 	u8 addr;
654f5473692STali Perry #endif
65556a1485bSTali Perry 
65656a1485bSTali Perry 	i2cctl1 = ioread8(bus->reg + NPCM_I2CCTL1);
65756a1485bSTali Perry 
65856a1485bSTali Perry 	npcm_i2c_disable(bus);
65956a1485bSTali Perry 	npcm_i2c_enable(bus);
66056a1485bSTali Perry 
66156a1485bSTali Perry 	/* Restore NPCM_I2CCTL1 Status */
66256a1485bSTali Perry 	i2cctl1 &= ~NPCM_I2CCTL1_RWS;
66356a1485bSTali Perry 	iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1);
66456a1485bSTali Perry 
66556a1485bSTali Perry 	/* Clear BB (BUS BUSY) bit */
66656a1485bSTali Perry 	iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
66756a1485bSTali Perry 	iowrite8(0xFF, bus->reg + NPCM_I2CST);
66856a1485bSTali Perry 
669e5222d40STali Perry 	/* Clear and disable EOB */
670e5222d40STali Perry 	npcm_i2c_eob_int(bus, false);
67156a1485bSTali Perry 
67256a1485bSTali Perry 	/* Clear all fifo bits: */
67356a1485bSTali Perry 	iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS);
67456a1485bSTali Perry 
675f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
676f5473692STali Perry 	if (bus->slave) {
677f5473692STali Perry 		addr = bus->slave->addr;
678f5473692STali Perry 		npcm_i2c_slave_enable(bus, I2C_SLAVE_ADDR1, addr, true);
679f5473692STali Perry 	}
680f5473692STali Perry #endif
681f5473692STali Perry 
682ffad0a35STyrone Ting 	/* Clear status bits for spurious interrupts */
683e5222d40STali Perry 	npcm_i2c_clear_master_status(bus);
684e5222d40STali Perry 
68556a1485bSTali Perry 	bus->state = I2C_IDLE;
68656a1485bSTali Perry }
68756a1485bSTali Perry 
68856a1485bSTali Perry static inline bool npcm_i2c_is_master(struct npcm_i2c *bus)
68956a1485bSTali Perry {
69056a1485bSTali Perry 	return !!FIELD_GET(NPCM_I2CST_MASTER, ioread8(bus->reg + NPCM_I2CST));
69156a1485bSTali Perry }
69256a1485bSTali Perry 
69356a1485bSTali Perry static void npcm_i2c_callback(struct npcm_i2c *bus,
69456a1485bSTali Perry 			      enum i2c_state_ind op_status, u16 info)
69556a1485bSTali Perry {
69656a1485bSTali Perry 	struct i2c_msg *msgs;
69756a1485bSTali Perry 	int msgs_num;
69892e73d80SWilliam A. Kennington III 	bool do_complete = false;
69956a1485bSTali Perry 
70056a1485bSTali Perry 	msgs = bus->msgs;
70156a1485bSTali Perry 	msgs_num = bus->msgs_num;
70256a1485bSTali Perry 	/*
70356a1485bSTali Perry 	 * check that transaction was not timed-out, and msgs still
70456a1485bSTali Perry 	 * holds a valid value.
70556a1485bSTali Perry 	 */
70656a1485bSTali Perry 	if (!msgs)
70756a1485bSTali Perry 		return;
70856a1485bSTali Perry 
70956a1485bSTali Perry 	if (completion_done(&bus->cmd_complete))
71056a1485bSTali Perry 		return;
71156a1485bSTali Perry 
71256a1485bSTali Perry 	switch (op_status) {
71356a1485bSTali Perry 	case I2C_MASTER_DONE_IND:
71456a1485bSTali Perry 		bus->cmd_err = bus->msgs_num;
7150bf58eb1STali Perry 		if (bus->tx_complete_cnt < ULLONG_MAX)
7160bf58eb1STali Perry 			bus->tx_complete_cnt++;
71756a1485bSTali Perry 		fallthrough;
71856a1485bSTali Perry 	case I2C_BLOCK_BYTES_ERR_IND:
71956a1485bSTali Perry 		/* Master tx finished and all transmit bytes were sent */
72056a1485bSTali Perry 		if (bus->msgs) {
72156a1485bSTali Perry 			if (msgs[0].flags & I2C_M_RD)
72256a1485bSTali Perry 				msgs[0].len = info;
72356a1485bSTali Perry 			else if (msgs_num == 2 &&
72456a1485bSTali Perry 				 msgs[1].flags & I2C_M_RD)
72556a1485bSTali Perry 				msgs[1].len = info;
72656a1485bSTali Perry 		}
72792e73d80SWilliam A. Kennington III 		do_complete = true;
72856a1485bSTali Perry 		break;
72956a1485bSTali Perry 	case I2C_NACK_IND:
73056a1485bSTali Perry 		/* MASTER transmit got a NACK before tx all bytes */
73156a1485bSTali Perry 		bus->cmd_err = -ENXIO;
73292e73d80SWilliam A. Kennington III 		do_complete = true;
73356a1485bSTali Perry 		break;
73456a1485bSTali Perry 	case I2C_BUS_ERR_IND:
73556a1485bSTali Perry 		/* Bus error */
73656a1485bSTali Perry 		bus->cmd_err = -EAGAIN;
73792e73d80SWilliam A. Kennington III 		do_complete = true;
73856a1485bSTali Perry 		break;
73956a1485bSTali Perry 	case I2C_WAKE_UP_IND:
74056a1485bSTali Perry 		/* I2C wake up */
74156a1485bSTali Perry 		break;
74256a1485bSTali Perry 	default:
74356a1485bSTali Perry 		break;
74456a1485bSTali Perry 	}
74556a1485bSTali Perry 
74656a1485bSTali Perry 	bus->operation = I2C_NO_OPER;
747f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
748f5473692STali Perry 	if (bus->slave)
749f5473692STali Perry 		bus->master_or_slave = I2C_SLAVE;
750f5473692STali Perry #endif
75192e73d80SWilliam A. Kennington III 	if (do_complete)
75292e73d80SWilliam A. Kennington III 		complete(&bus->cmd_complete);
75356a1485bSTali Perry }
75456a1485bSTali Perry 
75556a1485bSTali Perry static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus)
75656a1485bSTali Perry {
75756a1485bSTali Perry 	if (bus->operation == I2C_WRITE_OPER)
758bbc38ed5STyrone Ting 		return (bus->data->txf_sts_tx_bytes &
75956a1485bSTali Perry 			ioread8(bus->reg + NPCM_I2CTXF_STS));
76056a1485bSTali Perry 	if (bus->operation == I2C_READ_OPER)
761bbc38ed5STyrone Ting 		return (bus->data->rxf_sts_rx_bytes &
76256a1485bSTali Perry 			ioread8(bus->reg + NPCM_I2CRXF_STS));
76356a1485bSTali Perry 	return 0;
76456a1485bSTali Perry }
76556a1485bSTali Perry 
76656a1485bSTali Perry static void npcm_i2c_write_to_fifo_master(struct npcm_i2c *bus, u16 max_bytes)
76756a1485bSTali Perry {
76856a1485bSTali Perry 	u8 size_free_fifo;
76956a1485bSTali Perry 
77056a1485bSTali Perry 	/*
77156a1485bSTali Perry 	 * Fill the FIFO, while the FIFO is not full and there are more bytes
77256a1485bSTali Perry 	 * to write
77356a1485bSTali Perry 	 */
774bbc38ed5STyrone Ting 	size_free_fifo = bus->data->fifo_size - npcm_i2c_fifo_usage(bus);
77556a1485bSTali Perry 	while (max_bytes-- && size_free_fifo) {
77656a1485bSTali Perry 		if (bus->wr_ind < bus->wr_size)
77756a1485bSTali Perry 			npcm_i2c_wr_byte(bus, bus->wr_buf[bus->wr_ind++]);
77856a1485bSTali Perry 		else
77956a1485bSTali Perry 			npcm_i2c_wr_byte(bus, 0xFF);
780bbc38ed5STyrone Ting 		size_free_fifo = bus->data->fifo_size - npcm_i2c_fifo_usage(bus);
78156a1485bSTali Perry 	}
78256a1485bSTali Perry }
78356a1485bSTali Perry 
78456a1485bSTali Perry /*
78556a1485bSTali Perry  * npcm_i2c_set_fifo:
78656a1485bSTali Perry  * configure the FIFO before using it. If nread is -1 RX FIFO will not be
78756a1485bSTali Perry  * configured. same for nwrite
78856a1485bSTali Perry  */
78956a1485bSTali Perry static void npcm_i2c_set_fifo(struct npcm_i2c *bus, int nread, int nwrite)
79056a1485bSTali Perry {
79156a1485bSTali Perry 	u8 rxf_ctl = 0;
79256a1485bSTali Perry 
79356a1485bSTali Perry 	if (!bus->fifo_use)
79456a1485bSTali Perry 		return;
79556a1485bSTali Perry 	npcm_i2c_select_bank(bus, I2C_BANK_1);
79656a1485bSTali Perry 	npcm_i2c_clear_tx_fifo(bus);
79756a1485bSTali Perry 	npcm_i2c_clear_rx_fifo(bus);
79856a1485bSTali Perry 
79956a1485bSTali Perry 	/* configure RX FIFO */
80056a1485bSTali Perry 	if (nread > 0) {
801bbc38ed5STyrone Ting 		rxf_ctl = min_t(int, nread, bus->data->fifo_size);
80256a1485bSTali Perry 
80356a1485bSTali Perry 		/* set LAST bit. if LAST is set next FIFO packet is nacked */
804bbc38ed5STyrone Ting 		if (nread <= bus->data->fifo_size)
805bbc38ed5STyrone Ting 			rxf_ctl |= bus->data->rxf_ctl_last_pec;
80656a1485bSTali Perry 
80756a1485bSTali Perry 		/*
80856a1485bSTali Perry 		 * if we are about to read the first byte in blk rd mode,
80956a1485bSTali Perry 		 * don't NACK it. If slave returns zero size HW can't NACK
8100c47dd7dSJonathan Neuschäfer 		 * it immediately, it will read extra byte and then NACK.
81156a1485bSTali Perry 		 */
81256a1485bSTali Perry 		if (bus->rd_ind == 0 && bus->read_block_use) {
81356a1485bSTali Perry 			/* set fifo to read one byte, no last: */
81456a1485bSTali Perry 			rxf_ctl = 1;
81556a1485bSTali Perry 		}
81656a1485bSTali Perry 
81756a1485bSTali Perry 		/* set fifo size: */
81856a1485bSTali Perry 		iowrite8(rxf_ctl, bus->reg + NPCM_I2CRXF_CTL);
81956a1485bSTali Perry 	}
82056a1485bSTali Perry 
82156a1485bSTali Perry 	/* configure TX FIFO */
82256a1485bSTali Perry 	if (nwrite > 0) {
823bbc38ed5STyrone Ting 		if (nwrite > bus->data->fifo_size)
82456a1485bSTali Perry 			/* data to send is more then FIFO size. */
825bbc38ed5STyrone Ting 			iowrite8(bus->data->fifo_size, bus->reg + NPCM_I2CTXF_CTL);
82656a1485bSTali Perry 		else
82756a1485bSTali Perry 			iowrite8(nwrite, bus->reg + NPCM_I2CTXF_CTL);
82856a1485bSTali Perry 
82956a1485bSTali Perry 		npcm_i2c_clear_tx_fifo(bus);
83056a1485bSTali Perry 	}
83156a1485bSTali Perry }
83256a1485bSTali Perry 
83356a1485bSTali Perry static void npcm_i2c_read_fifo(struct npcm_i2c *bus, u8 bytes_in_fifo)
83456a1485bSTali Perry {
83556a1485bSTali Perry 	u8 data;
83656a1485bSTali Perry 
83756a1485bSTali Perry 	while (bytes_in_fifo--) {
83856a1485bSTali Perry 		data = npcm_i2c_rd_byte(bus);
83956a1485bSTali Perry 		if (bus->rd_ind < bus->rd_size)
84056a1485bSTali Perry 			bus->rd_buf[bus->rd_ind++] = data;
84156a1485bSTali Perry 	}
84256a1485bSTali Perry }
84356a1485bSTali Perry 
84456a1485bSTali Perry static void npcm_i2c_master_abort(struct npcm_i2c *bus)
84556a1485bSTali Perry {
84656a1485bSTali Perry 	/* Only current master is allowed to issue a stop condition */
84756a1485bSTali Perry 	if (!npcm_i2c_is_master(bus))
84856a1485bSTali Perry 		return;
84956a1485bSTali Perry 
85056a1485bSTali Perry 	npcm_i2c_eob_int(bus, true);
85156a1485bSTali Perry 	npcm_i2c_master_stop(bus);
85256a1485bSTali Perry 	npcm_i2c_clear_master_status(bus);
85356a1485bSTali Perry }
85456a1485bSTali Perry 
855f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
856f5473692STali Perry static u8 npcm_i2c_get_slave_addr(struct npcm_i2c *bus, enum i2c_addr addr_type)
857f5473692STali Perry {
858f5473692STali Perry 	u8 slave_add;
859f5473692STali Perry 
86047d506d1STali Perry 	if (addr_type > I2C_SLAVE_ADDR2 && addr_type <= I2C_SLAVE_ADDR10)
86147d506d1STali Perry 		dev_err(bus->dev, "get slave: try to use more than 2 SA not supported\n");
862f5473692STali Perry 
863f5473692STali Perry 	slave_add = ioread8(bus->reg + npcm_i2caddr[(int)addr_type]);
864f5473692STali Perry 
865f5473692STali Perry 	return slave_add;
866f5473692STali Perry }
867f5473692STali Perry 
868f5473692STali Perry static int npcm_i2c_remove_slave_addr(struct npcm_i2c *bus, u8 slave_add)
869f5473692STali Perry {
870f5473692STali Perry 	int i;
871f5473692STali Perry 
872f5473692STali Perry 	/* Set the enable bit */
873f5473692STali Perry 	slave_add |= 0x80;
87447d506d1STali Perry 
87547d506d1STali Perry 	for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR_SUPPORTED; i++) {
876f5473692STali Perry 		if (ioread8(bus->reg + npcm_i2caddr[i]) == slave_add)
877f5473692STali Perry 			iowrite8(0, bus->reg + npcm_i2caddr[i]);
878f5473692STali Perry 	}
87947d506d1STali Perry 
880f5473692STali Perry 	return 0;
881f5473692STali Perry }
882f5473692STali Perry 
883f5473692STali Perry static void npcm_i2c_write_fifo_slave(struct npcm_i2c *bus, u16 max_bytes)
884f5473692STali Perry {
885f5473692STali Perry 	/*
886f5473692STali Perry 	 * Fill the FIFO, while the FIFO is not full and there are more bytes
887f5473692STali Perry 	 * to write
888f5473692STali Perry 	 */
889f5473692STali Perry 	npcm_i2c_clear_fifo_int(bus);
890f5473692STali Perry 	npcm_i2c_clear_tx_fifo(bus);
891f5473692STali Perry 	iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
892bbc38ed5STyrone Ting 	while (max_bytes-- && bus->data->fifo_size != npcm_i2c_fifo_usage(bus)) {
893f5473692STali Perry 		if (bus->slv_wr_size <= 0)
894f5473692STali Perry 			break;
895bbc38ed5STyrone Ting 		bus->slv_wr_ind = bus->slv_wr_ind & (bus->data->fifo_size - 1);
896f5473692STali Perry 		npcm_i2c_wr_byte(bus, bus->slv_wr_buf[bus->slv_wr_ind]);
897f5473692STali Perry 		bus->slv_wr_ind++;
898bbc38ed5STyrone Ting 		bus->slv_wr_ind = bus->slv_wr_ind & (bus->data->fifo_size - 1);
899f5473692STali Perry 		bus->slv_wr_size--;
900f5473692STali Perry 	}
901f5473692STali Perry }
902f5473692STali Perry 
903f5473692STali Perry static void npcm_i2c_read_fifo_slave(struct npcm_i2c *bus, u8 bytes_in_fifo)
904f5473692STali Perry {
905f5473692STali Perry 	u8 data;
906f5473692STali Perry 
907f5473692STali Perry 	if (!bus->slave)
908f5473692STali Perry 		return;
909f5473692STali Perry 
910f5473692STali Perry 	while (bytes_in_fifo--) {
911f5473692STali Perry 		data = npcm_i2c_rd_byte(bus);
912f5473692STali Perry 
913bbc38ed5STyrone Ting 		bus->slv_rd_ind = bus->slv_rd_ind & (bus->data->fifo_size - 1);
914f5473692STali Perry 		bus->slv_rd_buf[bus->slv_rd_ind] = data;
915f5473692STali Perry 		bus->slv_rd_ind++;
916f5473692STali Perry 
917f5473692STali Perry 		/* 1st byte is length in block protocol: */
918f5473692STali Perry 		if (bus->slv_rd_ind == 1 && bus->read_block_use)
919f5473692STali Perry 			bus->slv_rd_size = data + bus->PEC_use + 1;
920f5473692STali Perry 	}
921f5473692STali Perry }
922f5473692STali Perry 
923f5473692STali Perry static int npcm_i2c_slave_get_wr_buf(struct npcm_i2c *bus)
924f5473692STali Perry {
925f5473692STali Perry 	int i;
926f5473692STali Perry 	u8 value;
927f5473692STali Perry 	int ind;
928f5473692STali Perry 	int ret = bus->slv_wr_ind;
929f5473692STali Perry 
930f5473692STali Perry 	/* fill a cyclic buffer */
931bbc38ed5STyrone Ting 	for (i = 0; i < bus->data->fifo_size; i++) {
932bbc38ed5STyrone Ting 		if (bus->slv_wr_size >= bus->data->fifo_size)
933f5473692STali Perry 			break;
934d7aa1b14STali Perry 		if (bus->state == I2C_SLAVE_MATCH) {
935f5473692STali Perry 			i2c_slave_event(bus->slave, I2C_SLAVE_READ_REQUESTED, &value);
936d7aa1b14STali Perry 			bus->state = I2C_OPER_STARTED;
937d7aa1b14STali Perry 		} else {
938f5473692STali Perry 			i2c_slave_event(bus->slave, I2C_SLAVE_READ_PROCESSED, &value);
939f5473692STali Perry 		}
940bbc38ed5STyrone Ting 		ind = (bus->slv_wr_ind + bus->slv_wr_size) & (bus->data->fifo_size - 1);
941f5473692STali Perry 		bus->slv_wr_buf[ind] = value;
942f5473692STali Perry 		bus->slv_wr_size++;
943f5473692STali Perry 	}
944bbc38ed5STyrone Ting 	return bus->data->fifo_size - ret;
945f5473692STali Perry }
946f5473692STali Perry 
947f5473692STali Perry static void npcm_i2c_slave_send_rd_buf(struct npcm_i2c *bus)
948f5473692STali Perry {
949f5473692STali Perry 	int i;
950f5473692STali Perry 
951f5473692STali Perry 	for (i = 0; i < bus->slv_rd_ind; i++)
952f5473692STali Perry 		i2c_slave_event(bus->slave, I2C_SLAVE_WRITE_RECEIVED,
953f5473692STali Perry 				&bus->slv_rd_buf[i]);
954f5473692STali Perry 	/*
955f5473692STali Perry 	 * once we send bytes up, need to reset the counter of the wr buf
956f5473692STali Perry 	 * got data from master (new offset in device), ignore wr fifo:
957f5473692STali Perry 	 */
958f5473692STali Perry 	if (bus->slv_rd_ind) {
959f5473692STali Perry 		bus->slv_wr_size = 0;
960f5473692STali Perry 		bus->slv_wr_ind = 0;
961f5473692STali Perry 	}
962f5473692STali Perry 
963f5473692STali Perry 	bus->slv_rd_ind = 0;
964f5473692STali Perry 	bus->slv_rd_size = bus->adap.quirks->max_read_len;
965f5473692STali Perry 
966f5473692STali Perry 	npcm_i2c_clear_fifo_int(bus);
967f5473692STali Perry 	npcm_i2c_clear_rx_fifo(bus);
968f5473692STali Perry }
969f5473692STali Perry 
970f5473692STali Perry static void npcm_i2c_slave_receive(struct npcm_i2c *bus, u16 nread,
971f5473692STali Perry 				   u8 *read_data)
972f5473692STali Perry {
973f5473692STali Perry 	bus->state = I2C_OPER_STARTED;
974f5473692STali Perry 	bus->operation = I2C_READ_OPER;
975f5473692STali Perry 	bus->slv_rd_size = nread;
976f5473692STali Perry 	bus->slv_rd_ind = 0;
977f5473692STali Perry 
978f5473692STali Perry 	iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
979bbc38ed5STyrone Ting 	iowrite8(bus->data->fifo_size, bus->reg + NPCM_I2CRXF_CTL);
980f5473692STali Perry 	npcm_i2c_clear_tx_fifo(bus);
981f5473692STali Perry 	npcm_i2c_clear_rx_fifo(bus);
982f5473692STali Perry }
983f5473692STali Perry 
984f5473692STali Perry static void npcm_i2c_slave_xmit(struct npcm_i2c *bus, u16 nwrite,
985f5473692STali Perry 				u8 *write_data)
986f5473692STali Perry {
987f5473692STali Perry 	if (nwrite == 0)
988f5473692STali Perry 		return;
989f5473692STali Perry 
990f5473692STali Perry 	bus->operation = I2C_WRITE_OPER;
991f5473692STali Perry 
992f5473692STali Perry 	/* get the next buffer */
993f5473692STali Perry 	npcm_i2c_slave_get_wr_buf(bus);
994f5473692STali Perry 	npcm_i2c_write_fifo_slave(bus, nwrite);
995f5473692STali Perry }
996f5473692STali Perry 
997f5473692STali Perry /*
998f5473692STali Perry  * npcm_i2c_slave_wr_buf_sync:
999f5473692STali Perry  * currently slave IF only supports single byte operations.
10000c47dd7dSJonathan Neuschäfer  * in order to utilize the npcm HW FIFO, the driver will ask for 16 bytes
1001f5473692STali Perry  * at a time, pack them in buffer, and then transmit them all together
1002f5473692STali Perry  * to the FIFO and onward to the bus.
1003f5473692STali Perry  * NACK on read will be once reached to bus->adap->quirks->max_read_len.
1004f5473692STali Perry  * sending a NACK wherever the backend requests for it is not supported.
1005f5473692STali Perry  * the next two functions allow reading to local buffer before writing it all
1006f5473692STali Perry  * to the HW FIFO.
1007f5473692STali Perry  */
1008f5473692STali Perry static void npcm_i2c_slave_wr_buf_sync(struct npcm_i2c *bus)
1009f5473692STali Perry {
1010f5473692STali Perry 	int left_in_fifo;
1011f5473692STali Perry 
1012bbc38ed5STyrone Ting 	left_in_fifo = bus->data->txf_sts_tx_bytes &
1013bbc38ed5STyrone Ting 			ioread8(bus->reg + NPCM_I2CTXF_STS);
1014f5473692STali Perry 
1015f5473692STali Perry 	/* fifo already full: */
1016bbc38ed5STyrone Ting 	if (left_in_fifo >= bus->data->fifo_size ||
1017bbc38ed5STyrone Ting 	    bus->slv_wr_size >= bus->data->fifo_size)
1018f5473692STali Perry 		return;
1019f5473692STali Perry 
1020f5473692STali Perry 	/* update the wr fifo index back to the untransmitted bytes: */
1021f5473692STali Perry 	bus->slv_wr_ind = bus->slv_wr_ind - left_in_fifo;
1022f5473692STali Perry 	bus->slv_wr_size = bus->slv_wr_size + left_in_fifo;
1023f5473692STali Perry 
1024f5473692STali Perry 	if (bus->slv_wr_ind < 0)
1025bbc38ed5STyrone Ting 		bus->slv_wr_ind += bus->data->fifo_size;
1026f5473692STali Perry }
1027f5473692STali Perry 
1028f5473692STali Perry static void npcm_i2c_slave_rd_wr(struct npcm_i2c *bus)
1029f5473692STali Perry {
1030f5473692STali Perry 	if (NPCM_I2CST_XMIT & ioread8(bus->reg + NPCM_I2CST)) {
1031f5473692STali Perry 		/*
1032f5473692STali Perry 		 * Slave got an address match with direction bit 1 so it should
1033f5473692STali Perry 		 * transmit data. Write till the master will NACK
1034f5473692STali Perry 		 */
1035f5473692STali Perry 		bus->operation = I2C_WRITE_OPER;
1036f5473692STali Perry 		npcm_i2c_slave_xmit(bus, bus->adap.quirks->max_write_len,
1037f5473692STali Perry 				    bus->slv_wr_buf);
1038f5473692STali Perry 	} else {
1039f5473692STali Perry 		/*
1040f5473692STali Perry 		 * Slave got an address match with direction bit 0 so it should
1041f5473692STali Perry 		 * receive data.
1042f5473692STali Perry 		 * this module does not support saying no to bytes.
1043f5473692STali Perry 		 * it will always ACK.
1044f5473692STali Perry 		 */
1045f5473692STali Perry 		bus->operation = I2C_READ_OPER;
1046f5473692STali Perry 		npcm_i2c_read_fifo_slave(bus, npcm_i2c_fifo_usage(bus));
1047f5473692STali Perry 		bus->stop_ind = I2C_SLAVE_RCV_IND;
1048f5473692STali Perry 		npcm_i2c_slave_send_rd_buf(bus);
1049f5473692STali Perry 		npcm_i2c_slave_receive(bus, bus->adap.quirks->max_read_len,
1050f5473692STali Perry 				       bus->slv_rd_buf);
1051f5473692STali Perry 	}
1052f5473692STali Perry }
1053f5473692STali Perry 
1054f5473692STali Perry static irqreturn_t npcm_i2c_int_slave_handler(struct npcm_i2c *bus)
1055f5473692STali Perry {
1056f5473692STali Perry 	u8 val;
1057f5473692STali Perry 	irqreturn_t ret = IRQ_NONE;
1058f5473692STali Perry 	u8 i2cst = ioread8(bus->reg + NPCM_I2CST);
1059f5473692STali Perry 
1060f5473692STali Perry 	/* Slave: A NACK has occurred */
1061f5473692STali Perry 	if (NPCM_I2CST_NEGACK & i2cst) {
1062f5473692STali Perry 		bus->stop_ind = I2C_NACK_IND;
1063f5473692STali Perry 		npcm_i2c_slave_wr_buf_sync(bus);
1064f5473692STali Perry 		if (bus->fifo_use)
1065f5473692STali Perry 			/* clear the FIFO */
1066f5473692STali Perry 			iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO,
1067f5473692STali Perry 				 bus->reg + NPCM_I2CFIF_CTS);
1068f5473692STali Perry 
1069f5473692STali Perry 		/* In slave write, NACK is OK, otherwise it is a problem */
1070f5473692STali Perry 		bus->stop_ind = I2C_NO_STATUS_IND;
1071f5473692STali Perry 		bus->operation = I2C_NO_OPER;
1072f5473692STali Perry 		bus->own_slave_addr = 0xFF;
1073f5473692STali Perry 
1074f5473692STali Perry 		/*
1075f5473692STali Perry 		 * Slave has to wait for STOP to decide this is the end
1076f5473692STali Perry 		 * of the transaction. tx is not yet considered as done
1077f5473692STali Perry 		 */
1078f5473692STali Perry 		iowrite8(NPCM_I2CST_NEGACK, bus->reg + NPCM_I2CST);
1079f5473692STali Perry 
1080f5473692STali Perry 		ret = IRQ_HANDLED;
1081f5473692STali Perry 	}
1082f5473692STali Perry 
1083f5473692STali Perry 	/* Slave mode: a Bus Error (BER) has been identified */
1084f5473692STali Perry 	if (NPCM_I2CST_BER & i2cst) {
1085f5473692STali Perry 		/*
1086f5473692STali Perry 		 * Check whether bus arbitration or Start or Stop during data
1087f5473692STali Perry 		 * xfer bus arbitration problem should not result in recovery
1088f5473692STali Perry 		 */
1089f5473692STali Perry 		bus->stop_ind = I2C_BUS_ERR_IND;
1090f5473692STali Perry 
1091f5473692STali Perry 		/* wait for bus busy before clear fifo */
1092f5473692STali Perry 		iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS);
1093f5473692STali Perry 
1094f5473692STali Perry 		bus->state = I2C_IDLE;
1095f5473692STali Perry 
1096f5473692STali Perry 		/*
1097f5473692STali Perry 		 * in BER case we might get 2 interrupts: one for slave one for
1098f5473692STali Perry 		 * master ( for a channel which is master\slave switching)
1099f5473692STali Perry 		 */
1100f5473692STali Perry 		if (completion_done(&bus->cmd_complete) == false) {
1101f5473692STali Perry 			bus->cmd_err = -EIO;
1102f5473692STali Perry 			complete(&bus->cmd_complete);
1103f5473692STali Perry 		}
1104f5473692STali Perry 		bus->own_slave_addr = 0xFF;
1105f5473692STali Perry 		iowrite8(NPCM_I2CST_BER, bus->reg + NPCM_I2CST);
1106f5473692STali Perry 		ret = IRQ_HANDLED;
1107f5473692STali Perry 	}
1108f5473692STali Perry 
1109f5473692STali Perry 	/* A Slave Stop Condition has been identified */
1110f5473692STali Perry 	if (NPCM_I2CST_SLVSTP & i2cst) {
1111f5473692STali Perry 		u8 bytes_in_fifo = npcm_i2c_fifo_usage(bus);
1112f5473692STali Perry 
1113f5473692STali Perry 		bus->stop_ind = I2C_SLAVE_DONE_IND;
1114f5473692STali Perry 
1115f5473692STali Perry 		if (bus->operation == I2C_READ_OPER)
1116f5473692STali Perry 			npcm_i2c_read_fifo_slave(bus, bytes_in_fifo);
1117f5473692STali Perry 
1118f5473692STali Perry 		/* if the buffer is empty nothing will be sent */
1119f5473692STali Perry 		npcm_i2c_slave_send_rd_buf(bus);
1120f5473692STali Perry 
1121f5473692STali Perry 		/* Slave done transmitting or receiving */
1122f5473692STali Perry 		bus->stop_ind = I2C_NO_STATUS_IND;
1123f5473692STali Perry 
1124f5473692STali Perry 		/*
1125f5473692STali Perry 		 * Note, just because we got here, it doesn't mean we through
1126f5473692STali Perry 		 * away the wr buffer.
1127f5473692STali Perry 		 * we keep it until the next received offset.
1128f5473692STali Perry 		 */
1129f5473692STali Perry 		bus->operation = I2C_NO_OPER;
1130f5473692STali Perry 		bus->own_slave_addr = 0xFF;
1131f5473692STali Perry 		i2c_slave_event(bus->slave, I2C_SLAVE_STOP, 0);
1132f5473692STali Perry 		iowrite8(NPCM_I2CST_SLVSTP, bus->reg + NPCM_I2CST);
1133f5473692STali Perry 		if (bus->fifo_use) {
1134f5473692STali Perry 			npcm_i2c_clear_fifo_int(bus);
1135f5473692STali Perry 			npcm_i2c_clear_rx_fifo(bus);
1136f5473692STali Perry 			npcm_i2c_clear_tx_fifo(bus);
1137f5473692STali Perry 
1138f5473692STali Perry 			iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO,
1139f5473692STali Perry 				 bus->reg + NPCM_I2CFIF_CTS);
1140f5473692STali Perry 		}
1141f5473692STali Perry 		bus->state = I2C_IDLE;
1142f5473692STali Perry 		ret = IRQ_HANDLED;
1143f5473692STali Perry 	}
1144f5473692STali Perry 
1145f5473692STali Perry 	/* restart condition occurred and Rx-FIFO was not empty */
1146f5473692STali Perry 	if (bus->fifo_use && FIELD_GET(NPCM_I2CFIF_CTS_SLVRSTR,
1147f5473692STali Perry 				       ioread8(bus->reg + NPCM_I2CFIF_CTS))) {
1148f5473692STali Perry 		bus->stop_ind = I2C_SLAVE_RESTART_IND;
1149f5473692STali Perry 		bus->master_or_slave = I2C_SLAVE;
1150f5473692STali Perry 		if (bus->operation == I2C_READ_OPER)
1151f5473692STali Perry 			npcm_i2c_read_fifo_slave(bus, npcm_i2c_fifo_usage(bus));
1152f5473692STali Perry 		bus->operation = I2C_WRITE_OPER;
1153f5473692STali Perry 		iowrite8(0, bus->reg + NPCM_I2CRXF_CTL);
1154f5473692STali Perry 		val = NPCM_I2CFIF_CTS_CLR_FIFO | NPCM_I2CFIF_CTS_SLVRSTR |
1155f5473692STali Perry 		      NPCM_I2CFIF_CTS_RXF_TXE;
1156f5473692STali Perry 		iowrite8(val, bus->reg + NPCM_I2CFIF_CTS);
1157f5473692STali Perry 		npcm_i2c_slave_rd_wr(bus);
1158f5473692STali Perry 		ret = IRQ_HANDLED;
1159f5473692STali Perry 	}
1160f5473692STali Perry 
1161f5473692STali Perry 	/* A Slave Address Match has been identified */
1162f5473692STali Perry 	if (NPCM_I2CST_NMATCH & i2cst) {
1163f5473692STali Perry 		u8 info = 0;
1164f5473692STali Perry 
1165f5473692STali Perry 		/* Address match automatically implies slave mode */
1166f5473692STali Perry 		bus->master_or_slave = I2C_SLAVE;
1167f5473692STali Perry 		npcm_i2c_clear_fifo_int(bus);
1168f5473692STali Perry 		npcm_i2c_clear_rx_fifo(bus);
1169f5473692STali Perry 		npcm_i2c_clear_tx_fifo(bus);
1170f5473692STali Perry 		iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
1171bbc38ed5STyrone Ting 		iowrite8(bus->data->fifo_size, bus->reg + NPCM_I2CRXF_CTL);
1172f5473692STali Perry 		if (NPCM_I2CST_XMIT & i2cst) {
1173f5473692STali Perry 			bus->operation = I2C_WRITE_OPER;
1174f5473692STali Perry 		} else {
1175f5473692STali Perry 			i2c_slave_event(bus->slave, I2C_SLAVE_WRITE_REQUESTED,
1176f5473692STali Perry 					&info);
1177f5473692STali Perry 			bus->operation = I2C_READ_OPER;
1178f5473692STali Perry 		}
1179f5473692STali Perry 		if (bus->own_slave_addr == 0xFF) {
1180f5473692STali Perry 			/* Check which type of address match */
1181f5473692STali Perry 			val = ioread8(bus->reg + NPCM_I2CCST);
1182f5473692STali Perry 			if (NPCM_I2CCST_MATCH & val) {
1183f5473692STali Perry 				u16 addr;
1184f5473692STali Perry 				enum i2c_addr eaddr;
1185f5473692STali Perry 				u8 i2ccst2;
1186f5473692STali Perry 				u8 i2ccst3;
1187f5473692STali Perry 
1188f5473692STali Perry 				i2ccst3 = ioread8(bus->reg + NPCM_I2CCST3);
1189f5473692STali Perry 				i2ccst2 = ioread8(bus->reg + NPCM_I2CCST2);
1190f5473692STali Perry 
1191f5473692STali Perry 				/*
1192f5473692STali Perry 				 * the i2c module can response to 10 own SA.
1193f5473692STali Perry 				 * check which one was addressed by the master.
11940c47dd7dSJonathan Neuschäfer 				 * respond to the first one.
1195f5473692STali Perry 				 */
1196f5473692STali Perry 				addr = ((i2ccst3 & 0x07) << 7) |
1197f5473692STali Perry 					(i2ccst2 & 0x7F);
1198f5473692STali Perry 				info = ffs(addr);
1199f5473692STali Perry 				eaddr = (enum i2c_addr)info;
1200f5473692STali Perry 				addr = npcm_i2c_get_slave_addr(bus, eaddr);
1201f5473692STali Perry 				addr &= 0x7F;
1202f5473692STali Perry 				bus->own_slave_addr = addr;
1203f5473692STali Perry 				if (bus->PEC_mask & BIT(info))
1204f5473692STali Perry 					bus->PEC_use = true;
1205f5473692STali Perry 				else
1206f5473692STali Perry 					bus->PEC_use = false;
1207f5473692STali Perry 			} else {
1208f5473692STali Perry 				if (NPCM_I2CCST_GCMATCH & val)
1209f5473692STali Perry 					bus->own_slave_addr = 0;
1210f5473692STali Perry 				if (NPCM_I2CCST_ARPMATCH & val)
1211f5473692STali Perry 					bus->own_slave_addr = 0x61;
1212f5473692STali Perry 			}
1213f5473692STali Perry 		} else {
1214f5473692STali Perry 			/*
1215f5473692STali Perry 			 *  Slave match can happen in two options:
1216f5473692STali Perry 			 *  1. Start, SA, read (slave read without further ado)
1217f5473692STali Perry 			 *  2. Start, SA, read, data, restart, SA, read,  ...
1218f5473692STali Perry 			 *     (slave read in fragmented mode)
1219f5473692STali Perry 			 *  3. Start, SA, write, data, restart, SA, read, ..
1220f5473692STali Perry 			 *     (regular write-read mode)
1221f5473692STali Perry 			 */
1222f5473692STali Perry 			if ((bus->state == I2C_OPER_STARTED &&
1223f5473692STali Perry 			     bus->operation == I2C_READ_OPER &&
1224f5473692STali Perry 			     bus->stop_ind == I2C_SLAVE_XMIT_IND) ||
1225f5473692STali Perry 			     bus->stop_ind == I2C_SLAVE_RCV_IND) {
1226f5473692STali Perry 				/* slave tx after slave rx w/o STOP */
1227f5473692STali Perry 				bus->stop_ind = I2C_SLAVE_RESTART_IND;
1228f5473692STali Perry 			}
1229f5473692STali Perry 		}
1230f5473692STali Perry 
1231f5473692STali Perry 		if (NPCM_I2CST_XMIT & i2cst)
1232f5473692STali Perry 			bus->stop_ind = I2C_SLAVE_XMIT_IND;
1233f5473692STali Perry 		else
1234f5473692STali Perry 			bus->stop_ind = I2C_SLAVE_RCV_IND;
1235f5473692STali Perry 		bus->state = I2C_SLAVE_MATCH;
1236f5473692STali Perry 		npcm_i2c_slave_rd_wr(bus);
1237f5473692STali Perry 		iowrite8(NPCM_I2CST_NMATCH, bus->reg + NPCM_I2CST);
1238f5473692STali Perry 		ret = IRQ_HANDLED;
1239f5473692STali Perry 	}
1240f5473692STali Perry 
1241f5473692STali Perry 	/* Slave SDA status is set - tx or rx */
1242f5473692STali Perry 	if ((NPCM_I2CST_SDAST & i2cst) ||
1243f5473692STali Perry 	    (bus->fifo_use &&
1244f5473692STali Perry 	    (npcm_i2c_tx_fifo_empty(bus) || npcm_i2c_rx_fifo_full(bus)))) {
1245f5473692STali Perry 		npcm_i2c_slave_rd_wr(bus);
1246f5473692STali Perry 		iowrite8(NPCM_I2CST_SDAST, bus->reg + NPCM_I2CST);
1247f5473692STali Perry 		ret = IRQ_HANDLED;
1248f5473692STali Perry 	} /* SDAST */
1249f5473692STali Perry 
1250e5222d40STali Perry 	/*
1251ffad0a35STyrone Ting 	 * If irq is not one of the above, make sure EOB is disabled and all
1252e5222d40STali Perry 	 * status bits are cleared.
1253e5222d40STali Perry 	 */
1254e5222d40STali Perry 	if (ret == IRQ_NONE) {
1255e5222d40STali Perry 		npcm_i2c_eob_int(bus, false);
1256e5222d40STali Perry 		npcm_i2c_clear_master_status(bus);
1257e5222d40STali Perry 	}
1258e5222d40STali Perry 
1259e5222d40STali Perry 	return IRQ_HANDLED;
1260f5473692STali Perry }
1261f5473692STali Perry 
1262f5473692STali Perry static int npcm_i2c_reg_slave(struct i2c_client *client)
1263f5473692STali Perry {
1264f5473692STali Perry 	unsigned long lock_flags;
1265f5473692STali Perry 	struct npcm_i2c *bus = i2c_get_adapdata(client->adapter);
1266f5473692STali Perry 
1267f5473692STali Perry 	bus->slave = client;
1268f5473692STali Perry 
1269f5473692STali Perry 	if (client->flags & I2C_CLIENT_TEN)
1270f5473692STali Perry 		return -EAFNOSUPPORT;
1271f5473692STali Perry 
1272f5473692STali Perry 	spin_lock_irqsave(&bus->lock, lock_flags);
1273f5473692STali Perry 
1274f5473692STali Perry 	npcm_i2c_init_params(bus);
1275f5473692STali Perry 	bus->slv_rd_size = 0;
1276f5473692STali Perry 	bus->slv_wr_size = 0;
1277f5473692STali Perry 	bus->slv_rd_ind = 0;
1278f5473692STali Perry 	bus->slv_wr_ind = 0;
1279f5473692STali Perry 	if (client->flags & I2C_CLIENT_PEC)
1280f5473692STali Perry 		bus->PEC_use = true;
1281f5473692STali Perry 
1282f5473692STali Perry 	dev_info(bus->dev, "i2c%d register slave SA=0x%x, PEC=%d\n", bus->num,
1283f5473692STali Perry 		 client->addr, bus->PEC_use);
1284f5473692STali Perry 
1285f5473692STali Perry 	npcm_i2c_slave_enable(bus, I2C_SLAVE_ADDR1, client->addr, true);
1286f5473692STali Perry 	npcm_i2c_clear_fifo_int(bus);
1287f5473692STali Perry 	npcm_i2c_clear_rx_fifo(bus);
1288f5473692STali Perry 	npcm_i2c_clear_tx_fifo(bus);
1289f5473692STali Perry 	npcm_i2c_slave_int_enable(bus, true);
1290f5473692STali Perry 
1291f5473692STali Perry 	spin_unlock_irqrestore(&bus->lock, lock_flags);
1292f5473692STali Perry 	return 0;
1293f5473692STali Perry }
1294f5473692STali Perry 
1295f5473692STali Perry static int npcm_i2c_unreg_slave(struct i2c_client *client)
1296f5473692STali Perry {
1297f5473692STali Perry 	struct npcm_i2c *bus = client->adapter->algo_data;
1298f5473692STali Perry 	unsigned long lock_flags;
1299f5473692STali Perry 
1300f5473692STali Perry 	spin_lock_irqsave(&bus->lock, lock_flags);
1301f5473692STali Perry 	if (!bus->slave) {
1302f5473692STali Perry 		spin_unlock_irqrestore(&bus->lock, lock_flags);
1303f5473692STali Perry 		return -EINVAL;
1304f5473692STali Perry 	}
1305f5473692STali Perry 	npcm_i2c_slave_int_enable(bus, false);
1306f5473692STali Perry 	npcm_i2c_remove_slave_addr(bus, client->addr);
1307f5473692STali Perry 	bus->slave = NULL;
1308f5473692STali Perry 	spin_unlock_irqrestore(&bus->lock, lock_flags);
1309f5473692STali Perry 	return 0;
1310f5473692STali Perry }
1311f5473692STali Perry #endif /* CONFIG_I2C_SLAVE */
1312f5473692STali Perry 
131356a1485bSTali Perry static void npcm_i2c_master_fifo_read(struct npcm_i2c *bus)
131456a1485bSTali Perry {
131556a1485bSTali Perry 	int rcount;
131656a1485bSTali Perry 	int fifo_bytes;
131756a1485bSTali Perry 	enum i2c_state_ind ind = I2C_MASTER_DONE_IND;
131856a1485bSTali Perry 
131956a1485bSTali Perry 	fifo_bytes = npcm_i2c_fifo_usage(bus);
132056a1485bSTali Perry 	rcount = bus->rd_size - bus->rd_ind;
132156a1485bSTali Perry 
132256a1485bSTali Perry 	/*
132356a1485bSTali Perry 	 * In order not to change the RX_TRH during transaction (we found that
132456a1485bSTali Perry 	 * this might be problematic if it takes too much time to read the FIFO)
132556a1485bSTali Perry 	 * we read the data in the following way. If the number of bytes to
132656a1485bSTali Perry 	 * read == FIFO Size + C (where C < FIFO Size)then first read C bytes
132756a1485bSTali Perry 	 * and in the next int we read rest of the data.
132856a1485bSTali Perry 	 */
1329bbc38ed5STyrone Ting 	if (rcount < (2 * bus->data->fifo_size) && rcount > bus->data->fifo_size)
1330bbc38ed5STyrone Ting 		fifo_bytes = rcount - bus->data->fifo_size;
133156a1485bSTali Perry 
133256a1485bSTali Perry 	if (rcount <= fifo_bytes) {
133356a1485bSTali Perry 		/* last bytes are about to be read - end of tx */
133456a1485bSTali Perry 		bus->state = I2C_STOP_PENDING;
133556a1485bSTali Perry 		bus->stop_ind = ind;
133656a1485bSTali Perry 		npcm_i2c_eob_int(bus, true);
133756a1485bSTali Perry 		/* Stop should be set before reading last byte. */
133856a1485bSTali Perry 		npcm_i2c_master_stop(bus);
133956a1485bSTali Perry 		npcm_i2c_read_fifo(bus, fifo_bytes);
134056a1485bSTali Perry 	} else {
134156a1485bSTali Perry 		npcm_i2c_read_fifo(bus, fifo_bytes);
134256a1485bSTali Perry 		rcount = bus->rd_size - bus->rd_ind;
134356a1485bSTali Perry 		npcm_i2c_set_fifo(bus, rcount, -1);
134456a1485bSTali Perry 	}
134556a1485bSTali Perry }
134656a1485bSTali Perry 
134756a1485bSTali Perry static void npcm_i2c_irq_master_handler_write(struct npcm_i2c *bus)
134856a1485bSTali Perry {
134956a1485bSTali Perry 	u16 wcount;
135056a1485bSTali Perry 
135156a1485bSTali Perry 	if (bus->fifo_use)
135256a1485bSTali Perry 		npcm_i2c_clear_tx_fifo(bus); /* clear the TX fifo status bit */
135356a1485bSTali Perry 
135456a1485bSTali Perry 	/* Master write operation - last byte handling */
135556a1485bSTali Perry 	if (bus->wr_ind == bus->wr_size) {
135656a1485bSTali Perry 		if (bus->fifo_use && npcm_i2c_fifo_usage(bus) > 0)
135756a1485bSTali Perry 			/*
135856a1485bSTali Perry 			 * No more bytes to send (to add to the FIFO),
135956a1485bSTali Perry 			 * however the FIFO is not empty yet. It is
136056a1485bSTali Perry 			 * still in the middle of tx. Currently there's nothing
136156a1485bSTali Perry 			 * to do except for waiting to the end of the tx
136256a1485bSTali Perry 			 * We will get an int when the FIFO will get empty.
136356a1485bSTali Perry 			 */
136456a1485bSTali Perry 			return;
136556a1485bSTali Perry 
136656a1485bSTali Perry 		if (bus->rd_size == 0) {
136756a1485bSTali Perry 			/* all bytes have been written, in wr only operation */
136856a1485bSTali Perry 			npcm_i2c_eob_int(bus, true);
136956a1485bSTali Perry 			bus->state = I2C_STOP_PENDING;
137056a1485bSTali Perry 			bus->stop_ind = I2C_MASTER_DONE_IND;
137156a1485bSTali Perry 			npcm_i2c_master_stop(bus);
137256a1485bSTali Perry 			/* Clear SDA Status bit (by writing dummy byte) */
137356a1485bSTali Perry 			npcm_i2c_wr_byte(bus, 0xFF);
137456a1485bSTali Perry 
137556a1485bSTali Perry 		} else {
137656a1485bSTali Perry 			/* last write-byte written on previous int - restart */
137756a1485bSTali Perry 			npcm_i2c_set_fifo(bus, bus->rd_size, -1);
137856a1485bSTali Perry 			/* Generate repeated start upon next write to SDA */
137956a1485bSTali Perry 			npcm_i2c_master_start(bus);
138056a1485bSTali Perry 
138156a1485bSTali Perry 			/*
138256a1485bSTali Perry 			 * Receiving one byte only - stall after successful
138356a1485bSTali Perry 			 * completion of send address byte. If we NACK here, and
138456a1485bSTali Perry 			 * slave doesn't ACK the address, we might
138556a1485bSTali Perry 			 * unintentionally NACK the next multi-byte read.
138656a1485bSTali Perry 			 */
138756a1485bSTali Perry 			if (bus->rd_size == 1)
138856a1485bSTali Perry 				npcm_i2c_stall_after_start(bus, true);
138956a1485bSTali Perry 
139056a1485bSTali Perry 			/* Next int will occur on read */
139156a1485bSTali Perry 			bus->operation = I2C_READ_OPER;
139256a1485bSTali Perry 			/* send the slave address in read direction */
139356a1485bSTali Perry 			npcm_i2c_wr_byte(bus, bus->dest_addr | 0x1);
139456a1485bSTali Perry 		}
139556a1485bSTali Perry 	} else {
139656a1485bSTali Perry 		/* write next byte not last byte and not slave address */
139756a1485bSTali Perry 		if (!bus->fifo_use || bus->wr_size == 1) {
139856a1485bSTali Perry 			npcm_i2c_wr_byte(bus, bus->wr_buf[bus->wr_ind++]);
139956a1485bSTali Perry 		} else {
140056a1485bSTali Perry 			wcount = bus->wr_size - bus->wr_ind;
140156a1485bSTali Perry 			npcm_i2c_set_fifo(bus, -1, wcount);
140256a1485bSTali Perry 			if (wcount)
140356a1485bSTali Perry 				npcm_i2c_write_to_fifo_master(bus, wcount);
140456a1485bSTali Perry 		}
140556a1485bSTali Perry 	}
140656a1485bSTali Perry }
140756a1485bSTali Perry 
140856a1485bSTali Perry static void npcm_i2c_irq_master_handler_read(struct npcm_i2c *bus)
140956a1485bSTali Perry {
141056a1485bSTali Perry 	u16 block_extra_bytes_size;
141156a1485bSTali Perry 	u8 data;
141256a1485bSTali Perry 
141356a1485bSTali Perry 	/* added bytes to the packet: */
141456a1485bSTali Perry 	block_extra_bytes_size = bus->read_block_use + bus->PEC_use;
141556a1485bSTali Perry 
141656a1485bSTali Perry 	/*
141756a1485bSTali Perry 	 * Perform master read, distinguishing between last byte and the rest of
141856a1485bSTali Perry 	 * the bytes. The last byte should be read when the clock is stopped
141956a1485bSTali Perry 	 */
142056a1485bSTali Perry 	if (bus->rd_ind == 0) { /* first byte handling: */
142156a1485bSTali Perry 		if (bus->read_block_use) {
142256a1485bSTali Perry 			/* first byte in block protocol is the size: */
142356a1485bSTali Perry 			data = npcm_i2c_rd_byte(bus);
142456a1485bSTali Perry 			data = clamp_val(data, 1, I2C_SMBUS_BLOCK_MAX);
142556a1485bSTali Perry 			bus->rd_size = data + block_extra_bytes_size;
142656a1485bSTali Perry 			bus->rd_buf[bus->rd_ind++] = data;
142756a1485bSTali Perry 
142856a1485bSTali Perry 			/* clear RX FIFO interrupt status: */
142956a1485bSTali Perry 			if (bus->fifo_use) {
143056a1485bSTali Perry 				data = ioread8(bus->reg + NPCM_I2CFIF_CTS);
143156a1485bSTali Perry 				data = data | NPCM_I2CFIF_CTS_RXF_TXE;
143256a1485bSTali Perry 				iowrite8(data, bus->reg + NPCM_I2CFIF_CTS);
143356a1485bSTali Perry 			}
143456a1485bSTali Perry 
143556a1485bSTali Perry 			npcm_i2c_set_fifo(bus, bus->rd_size - 1, -1);
143656a1485bSTali Perry 			npcm_i2c_stall_after_start(bus, false);
143756a1485bSTali Perry 		} else {
143856a1485bSTali Perry 			npcm_i2c_clear_tx_fifo(bus);
143956a1485bSTali Perry 			npcm_i2c_master_fifo_read(bus);
144056a1485bSTali Perry 		}
144156a1485bSTali Perry 	} else {
144256a1485bSTali Perry 		if (bus->rd_size == block_extra_bytes_size &&
144356a1485bSTali Perry 		    bus->read_block_use) {
144456a1485bSTali Perry 			bus->state = I2C_STOP_PENDING;
144556a1485bSTali Perry 			bus->stop_ind = I2C_BLOCK_BYTES_ERR_IND;
144656a1485bSTali Perry 			bus->cmd_err = -EIO;
144756a1485bSTali Perry 			npcm_i2c_eob_int(bus, true);
144856a1485bSTali Perry 			npcm_i2c_master_stop(bus);
144956a1485bSTali Perry 			npcm_i2c_read_fifo(bus, npcm_i2c_fifo_usage(bus));
145056a1485bSTali Perry 		} else {
145156a1485bSTali Perry 			npcm_i2c_master_fifo_read(bus);
145256a1485bSTali Perry 		}
145356a1485bSTali Perry 	}
145456a1485bSTali Perry }
145556a1485bSTali Perry 
145656a1485bSTali Perry static void npcm_i2c_irq_handle_nmatch(struct npcm_i2c *bus)
145756a1485bSTali Perry {
145856a1485bSTali Perry 	iowrite8(NPCM_I2CST_NMATCH, bus->reg + NPCM_I2CST);
145956a1485bSTali Perry 	npcm_i2c_nack(bus);
146056a1485bSTali Perry 	bus->stop_ind = I2C_BUS_ERR_IND;
146156a1485bSTali Perry 	npcm_i2c_callback(bus, bus->stop_ind, npcm_i2c_get_index(bus));
146256a1485bSTali Perry }
146356a1485bSTali Perry 
146456a1485bSTali Perry /* A NACK has occurred */
146556a1485bSTali Perry static void npcm_i2c_irq_handle_nack(struct npcm_i2c *bus)
146656a1485bSTali Perry {
146756a1485bSTali Perry 	u8 val;
146856a1485bSTali Perry 
146956a1485bSTali Perry 	if (bus->nack_cnt < ULLONG_MAX)
147056a1485bSTali Perry 		bus->nack_cnt++;
147156a1485bSTali Perry 
147256a1485bSTali Perry 	if (bus->fifo_use) {
147356a1485bSTali Perry 		/*
147456a1485bSTali Perry 		 * if there are still untransmitted bytes in TX FIFO
147556a1485bSTali Perry 		 * reduce them from wr_ind
147656a1485bSTali Perry 		 */
147756a1485bSTali Perry 		if (bus->operation == I2C_WRITE_OPER)
147856a1485bSTali Perry 			bus->wr_ind -= npcm_i2c_fifo_usage(bus);
147956a1485bSTali Perry 
148056a1485bSTali Perry 		/* clear the FIFO */
148156a1485bSTali Perry 		iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS);
148256a1485bSTali Perry 	}
148356a1485bSTali Perry 
148456a1485bSTali Perry 	/* In master write operation, got unexpected NACK */
148556a1485bSTali Perry 	bus->stop_ind = I2C_NACK_IND;
148656a1485bSTali Perry 	/* Only current master is allowed to issue Stop Condition */
148756a1485bSTali Perry 	if (npcm_i2c_is_master(bus)) {
148856a1485bSTali Perry 		/* stopping in the middle */
148956a1485bSTali Perry 		npcm_i2c_eob_int(bus, false);
149056a1485bSTali Perry 		npcm_i2c_master_stop(bus);
149156a1485bSTali Perry 
1492e5222d40STali Perry 		/* Clear SDA Status bit (by reading dummy byte) */
1493e5222d40STali Perry 		npcm_i2c_rd_byte(bus);
1494e5222d40STali Perry 
149556a1485bSTali Perry 		/*
149656a1485bSTali Perry 		 * The bus is released from stall only after the SW clears
149756a1485bSTali Perry 		 * NEGACK bit. Then a Stop condition is sent.
149856a1485bSTali Perry 		 */
149956a1485bSTali Perry 		npcm_i2c_clear_master_status(bus);
150056a1485bSTali Perry 		readx_poll_timeout_atomic(ioread8, bus->reg + NPCM_I2CCST, val,
150156a1485bSTali Perry 					  !(val & NPCM_I2CCST_BUSY), 10, 200);
1502ffad0a35STyrone Ting 		/* Verify no status bits are still set after bus is released */
1503e5222d40STali Perry 		npcm_i2c_clear_master_status(bus);
150456a1485bSTali Perry 	}
150556a1485bSTali Perry 	bus->state = I2C_IDLE;
150656a1485bSTali Perry 
150756a1485bSTali Perry 	/*
150856a1485bSTali Perry 	 * In Master mode, NACK should be cleared only after STOP.
150956a1485bSTali Perry 	 * In such case, the bus is released from stall only after the
151056a1485bSTali Perry 	 * software clears NACK bit. Then a Stop condition is sent.
151156a1485bSTali Perry 	 */
151256a1485bSTali Perry 	npcm_i2c_callback(bus, bus->stop_ind, bus->wr_ind);
151356a1485bSTali Perry }
151456a1485bSTali Perry 
151556a1485bSTali Perry 	/* Master mode: a Bus Error has been identified */
151656a1485bSTali Perry static void npcm_i2c_irq_handle_ber(struct npcm_i2c *bus)
151756a1485bSTali Perry {
151856a1485bSTali Perry 	if (bus->ber_cnt < ULLONG_MAX)
151956a1485bSTali Perry 		bus->ber_cnt++;
152056a1485bSTali Perry 	bus->stop_ind = I2C_BUS_ERR_IND;
152156a1485bSTali Perry 	if (npcm_i2c_is_master(bus)) {
152256a1485bSTali Perry 		npcm_i2c_master_abort(bus);
152356a1485bSTali Perry 	} else {
152456a1485bSTali Perry 		npcm_i2c_clear_master_status(bus);
152556a1485bSTali Perry 
152656a1485bSTali Perry 		/* Clear BB (BUS BUSY) bit */
152756a1485bSTali Perry 		iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
152856a1485bSTali Perry 
152956a1485bSTali Perry 		bus->cmd_err = -EAGAIN;
153056a1485bSTali Perry 		npcm_i2c_callback(bus, bus->stop_ind, npcm_i2c_get_index(bus));
153156a1485bSTali Perry 	}
153256a1485bSTali Perry 	bus->state = I2C_IDLE;
153356a1485bSTali Perry }
153456a1485bSTali Perry 
153556a1485bSTali Perry 	/* EOB: a master End Of Busy (meaning STOP completed) */
153656a1485bSTali Perry static void npcm_i2c_irq_handle_eob(struct npcm_i2c *bus)
153756a1485bSTali Perry {
153856a1485bSTali Perry 	npcm_i2c_eob_int(bus, false);
153956a1485bSTali Perry 	bus->state = I2C_IDLE;
154056a1485bSTali Perry 	npcm_i2c_callback(bus, bus->stop_ind, bus->rd_ind);
154156a1485bSTali Perry }
154256a1485bSTali Perry 
154356a1485bSTali Perry /* Address sent and requested stall occurred (Master mode) */
154456a1485bSTali Perry static void npcm_i2c_irq_handle_stall_after_start(struct npcm_i2c *bus)
154556a1485bSTali Perry {
154656a1485bSTali Perry 	if (npcm_i2c_is_quick(bus)) {
154756a1485bSTali Perry 		bus->state = I2C_STOP_PENDING;
154856a1485bSTali Perry 		bus->stop_ind = I2C_MASTER_DONE_IND;
154956a1485bSTali Perry 		npcm_i2c_eob_int(bus, true);
155056a1485bSTali Perry 		npcm_i2c_master_stop(bus);
155156a1485bSTali Perry 	} else if ((bus->rd_size == 1) && !bus->read_block_use) {
155256a1485bSTali Perry 		/*
155356a1485bSTali Perry 		 * Receiving one byte only - set NACK after ensuring
155456a1485bSTali Perry 		 * slave ACKed the address byte.
155556a1485bSTali Perry 		 */
155656a1485bSTali Perry 		npcm_i2c_nack(bus);
155756a1485bSTali Perry 	}
155856a1485bSTali Perry 
155956a1485bSTali Perry 	/* Reset stall-after-address-byte */
156056a1485bSTali Perry 	npcm_i2c_stall_after_start(bus, false);
156156a1485bSTali Perry 
156256a1485bSTali Perry 	/* Clear stall only after setting STOP */
156356a1485bSTali Perry 	iowrite8(NPCM_I2CST_STASTR, bus->reg + NPCM_I2CST);
156456a1485bSTali Perry }
156556a1485bSTali Perry 
156656a1485bSTali Perry /* SDA status is set - TX or RX, master */
156756a1485bSTali Perry static void npcm_i2c_irq_handle_sda(struct npcm_i2c *bus, u8 i2cst)
156856a1485bSTali Perry {
156956a1485bSTali Perry 	u8 fif_cts;
157056a1485bSTali Perry 
157156a1485bSTali Perry 	if (!npcm_i2c_is_master(bus))
157256a1485bSTali Perry 		return;
157356a1485bSTali Perry 
157456a1485bSTali Perry 	if (bus->state == I2C_IDLE) {
157556a1485bSTali Perry 		bus->stop_ind = I2C_WAKE_UP_IND;
157656a1485bSTali Perry 
157756a1485bSTali Perry 		if (npcm_i2c_is_quick(bus) || bus->read_block_use)
157856a1485bSTali Perry 			/*
157956a1485bSTali Perry 			 * Need to stall after successful
158056a1485bSTali Perry 			 * completion of sending address byte
158156a1485bSTali Perry 			 */
158256a1485bSTali Perry 			npcm_i2c_stall_after_start(bus, true);
158356a1485bSTali Perry 		else
158456a1485bSTali Perry 			npcm_i2c_stall_after_start(bus, false);
158556a1485bSTali Perry 
158656a1485bSTali Perry 		/*
158756a1485bSTali Perry 		 * Receiving one byte only - stall after successful completion
158856a1485bSTali Perry 		 * of sending address byte If we NACK here, and slave doesn't
158956a1485bSTali Perry 		 * ACK the address, we might unintentionally NACK the next
159056a1485bSTali Perry 		 * multi-byte read
159156a1485bSTali Perry 		 */
159256a1485bSTali Perry 		if (bus->wr_size == 0 && bus->rd_size == 1)
159356a1485bSTali Perry 			npcm_i2c_stall_after_start(bus, true);
159456a1485bSTali Perry 
159556a1485bSTali Perry 		/* Initiate I2C master tx */
159656a1485bSTali Perry 
159756a1485bSTali Perry 		/* select bank 1 for FIFO regs */
159856a1485bSTali Perry 		npcm_i2c_select_bank(bus, I2C_BANK_1);
159956a1485bSTali Perry 
160056a1485bSTali Perry 		fif_cts = ioread8(bus->reg + NPCM_I2CFIF_CTS);
160156a1485bSTali Perry 		fif_cts = fif_cts & ~NPCM_I2CFIF_CTS_SLVRSTR;
160256a1485bSTali Perry 
160356a1485bSTali Perry 		/* clear FIFO and relevant status bits. */
160456a1485bSTali Perry 		fif_cts = fif_cts | NPCM_I2CFIF_CTS_CLR_FIFO;
160556a1485bSTali Perry 		iowrite8(fif_cts, bus->reg + NPCM_I2CFIF_CTS);
160656a1485bSTali Perry 
160756a1485bSTali Perry 		/* re-enable */
160856a1485bSTali Perry 		fif_cts = fif_cts | NPCM_I2CFIF_CTS_RXF_TXE;
160956a1485bSTali Perry 		iowrite8(fif_cts, bus->reg + NPCM_I2CFIF_CTS);
161056a1485bSTali Perry 
161156a1485bSTali Perry 		/*
161256a1485bSTali Perry 		 * Configure the FIFO threshold:
161356a1485bSTali Perry 		 * according to the needed # of bytes to read.
161456a1485bSTali Perry 		 * Note: due to HW limitation can't config the rx fifo before it
161556a1485bSTali Perry 		 * got and ACK on the restart. LAST bit will not be reset unless
161656a1485bSTali Perry 		 * RX completed. It will stay set on the next tx.
161756a1485bSTali Perry 		 */
161856a1485bSTali Perry 		if (bus->wr_size)
161956a1485bSTali Perry 			npcm_i2c_set_fifo(bus, -1, bus->wr_size);
162056a1485bSTali Perry 		else
162156a1485bSTali Perry 			npcm_i2c_set_fifo(bus, bus->rd_size, -1);
162256a1485bSTali Perry 
162356a1485bSTali Perry 		bus->state = I2C_OPER_STARTED;
162456a1485bSTali Perry 
162556a1485bSTali Perry 		if (npcm_i2c_is_quick(bus) || bus->wr_size)
162656a1485bSTali Perry 			npcm_i2c_wr_byte(bus, bus->dest_addr);
162756a1485bSTali Perry 		else
162856a1485bSTali Perry 			npcm_i2c_wr_byte(bus, bus->dest_addr | BIT(0));
162956a1485bSTali Perry 	/* SDA interrupt, after start\restart */
163056a1485bSTali Perry 	} else {
1631*e365422cSTyrone Ting 		if (bus->operation == I2C_WRITE_OPER)
163256a1485bSTali Perry 			npcm_i2c_irq_master_handler_write(bus);
1633*e365422cSTyrone Ting 		else if (bus->operation == I2C_READ_OPER)
163456a1485bSTali Perry 			npcm_i2c_irq_master_handler_read(bus);
163556a1485bSTali Perry 	}
163656a1485bSTali Perry }
163756a1485bSTali Perry 
163856a1485bSTali Perry static int npcm_i2c_int_master_handler(struct npcm_i2c *bus)
163956a1485bSTali Perry {
164056a1485bSTali Perry 	u8 i2cst;
164156a1485bSTali Perry 	int ret = -EIO;
164256a1485bSTali Perry 
164356a1485bSTali Perry 	i2cst = ioread8(bus->reg + NPCM_I2CST);
164456a1485bSTali Perry 
164556a1485bSTali Perry 	if (FIELD_GET(NPCM_I2CST_NMATCH, i2cst)) {
164656a1485bSTali Perry 		npcm_i2c_irq_handle_nmatch(bus);
164756a1485bSTali Perry 		return 0;
164856a1485bSTali Perry 	}
164956a1485bSTali Perry 	/* A NACK has occurred */
165056a1485bSTali Perry 	if (FIELD_GET(NPCM_I2CST_NEGACK, i2cst)) {
165156a1485bSTali Perry 		npcm_i2c_irq_handle_nack(bus);
165256a1485bSTali Perry 		return 0;
165356a1485bSTali Perry 	}
165456a1485bSTali Perry 
165556a1485bSTali Perry 	/* Master mode: a Bus Error has been identified */
165656a1485bSTali Perry 	if (FIELD_GET(NPCM_I2CST_BER, i2cst)) {
165756a1485bSTali Perry 		npcm_i2c_irq_handle_ber(bus);
165856a1485bSTali Perry 		return 0;
165956a1485bSTali Perry 	}
166056a1485bSTali Perry 
166156a1485bSTali Perry 	/* EOB: a master End Of Busy (meaning STOP completed) */
166256a1485bSTali Perry 	if ((FIELD_GET(NPCM_I2CCTL1_EOBINTE,
166356a1485bSTali Perry 		       ioread8(bus->reg + NPCM_I2CCTL1)) == 1) &&
166456a1485bSTali Perry 	    (FIELD_GET(NPCM_I2CCST3_EO_BUSY,
166556a1485bSTali Perry 		       ioread8(bus->reg + NPCM_I2CCST3)))) {
166656a1485bSTali Perry 		npcm_i2c_irq_handle_eob(bus);
166756a1485bSTali Perry 		return 0;
166856a1485bSTali Perry 	}
166956a1485bSTali Perry 
167056a1485bSTali Perry 	/* Address sent and requested stall occurred (Master mode) */
167156a1485bSTali Perry 	if (FIELD_GET(NPCM_I2CST_STASTR, i2cst)) {
167256a1485bSTali Perry 		npcm_i2c_irq_handle_stall_after_start(bus);
167356a1485bSTali Perry 		ret = 0;
167456a1485bSTali Perry 	}
167556a1485bSTali Perry 
167656a1485bSTali Perry 	/* SDA status is set - TX or RX, master */
167756a1485bSTali Perry 	if (FIELD_GET(NPCM_I2CST_SDAST, i2cst) ||
167856a1485bSTali Perry 	    (bus->fifo_use &&
167956a1485bSTali Perry 	    (npcm_i2c_tx_fifo_empty(bus) || npcm_i2c_rx_fifo_full(bus)))) {
168056a1485bSTali Perry 		npcm_i2c_irq_handle_sda(bus, i2cst);
168156a1485bSTali Perry 		ret = 0;
168256a1485bSTali Perry 	}
168356a1485bSTali Perry 
168456a1485bSTali Perry 	return ret;
168556a1485bSTali Perry }
168656a1485bSTali Perry 
168756a1485bSTali Perry /* recovery using TGCLK functionality of the module */
168856a1485bSTali Perry static int npcm_i2c_recovery_tgclk(struct i2c_adapter *_adap)
168956a1485bSTali Perry {
169056a1485bSTali Perry 	u8               val;
169156a1485bSTali Perry 	u8               fif_cts;
169256a1485bSTali Perry 	bool             done = false;
169356a1485bSTali Perry 	int              status = -ENOTRECOVERABLE;
169456a1485bSTali Perry 	struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
169556a1485bSTali Perry 	/* Allow 3 bytes (27 toggles) to be read from the slave: */
169656a1485bSTali Perry 	int              iter = 27;
169756a1485bSTali Perry 
169856a1485bSTali Perry 	if ((npcm_i2c_get_SDA(_adap) == 1) && (npcm_i2c_get_SCL(_adap) == 1)) {
1699e5222d40STali Perry 		dev_dbg(bus->dev, "bus%d-0x%x recovery skipped, bus not stuck",
1700e5222d40STali Perry 			bus->num, bus->dest_addr);
170156a1485bSTali Perry 		npcm_i2c_reset(bus);
1702e5222d40STali Perry 		return 0;
170356a1485bSTali Perry 	}
170456a1485bSTali Perry 
170556a1485bSTali Perry 	npcm_i2c_int_enable(bus, false);
170656a1485bSTali Perry 	npcm_i2c_disable(bus);
170756a1485bSTali Perry 	npcm_i2c_enable(bus);
170856a1485bSTali Perry 	iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
170956a1485bSTali Perry 	npcm_i2c_clear_tx_fifo(bus);
171056a1485bSTali Perry 	npcm_i2c_clear_rx_fifo(bus);
171156a1485bSTali Perry 	iowrite8(0, bus->reg + NPCM_I2CRXF_CTL);
171256a1485bSTali Perry 	iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
171356a1485bSTali Perry 	npcm_i2c_stall_after_start(bus, false);
171456a1485bSTali Perry 
171556a1485bSTali Perry 	/* select bank 1 for FIFO regs */
171656a1485bSTali Perry 	npcm_i2c_select_bank(bus, I2C_BANK_1);
171756a1485bSTali Perry 
171856a1485bSTali Perry 	/* clear FIFO and relevant status bits. */
171956a1485bSTali Perry 	fif_cts = ioread8(bus->reg + NPCM_I2CFIF_CTS);
172056a1485bSTali Perry 	fif_cts &= ~NPCM_I2CFIF_CTS_SLVRSTR;
172156a1485bSTali Perry 	fif_cts |= NPCM_I2CFIF_CTS_CLR_FIFO;
172256a1485bSTali Perry 	iowrite8(fif_cts, bus->reg + NPCM_I2CFIF_CTS);
172356a1485bSTali Perry 	npcm_i2c_set_fifo(bus, -1, 0);
172456a1485bSTali Perry 
172556a1485bSTali Perry 	/* Repeat the following sequence until SDA is released */
172656a1485bSTali Perry 	do {
172756a1485bSTali Perry 		/* Issue a single SCL toggle */
172856a1485bSTali Perry 		iowrite8(NPCM_I2CCST_TGSCL, bus->reg + NPCM_I2CCST);
172956a1485bSTali Perry 		usleep_range(20, 30);
173056a1485bSTali Perry 		/* If SDA line is inactive (high), stop */
173156a1485bSTali Perry 		if (npcm_i2c_get_SDA(_adap)) {
173256a1485bSTali Perry 			done = true;
173356a1485bSTali Perry 			status = 0;
173456a1485bSTali Perry 		}
173556a1485bSTali Perry 	} while (!done && iter--);
173656a1485bSTali Perry 
173756a1485bSTali Perry 	/* If SDA line is released: send start-addr-stop, to re-sync. */
173856a1485bSTali Perry 	if (npcm_i2c_get_SDA(_adap)) {
173956a1485bSTali Perry 		/* Send an address byte in write direction: */
174056a1485bSTali Perry 		npcm_i2c_wr_byte(bus, bus->dest_addr);
174156a1485bSTali Perry 		npcm_i2c_master_start(bus);
174256a1485bSTali Perry 		/* Wait until START condition is sent */
174356a1485bSTali Perry 		status = readx_poll_timeout(npcm_i2c_get_SCL, _adap, val, !val,
174456a1485bSTali Perry 					    20, 200);
174556a1485bSTali Perry 		/* If START condition was sent */
174656a1485bSTali Perry 		if (npcm_i2c_is_master(bus) > 0) {
174756a1485bSTali Perry 			usleep_range(20, 30);
174856a1485bSTali Perry 			npcm_i2c_master_stop(bus);
174956a1485bSTali Perry 			usleep_range(200, 500);
175056a1485bSTali Perry 		}
175156a1485bSTali Perry 	}
175256a1485bSTali Perry 	npcm_i2c_reset(bus);
175356a1485bSTali Perry 	npcm_i2c_int_enable(bus, true);
175456a1485bSTali Perry 
175556a1485bSTali Perry 	if ((npcm_i2c_get_SDA(_adap) == 1) && (npcm_i2c_get_SCL(_adap) == 1))
175656a1485bSTali Perry 		status = 0;
175756a1485bSTali Perry 	else
175856a1485bSTali Perry 		status = -ENOTRECOVERABLE;
175956a1485bSTali Perry 	if (status) {
176056a1485bSTali Perry 		if (bus->rec_fail_cnt < ULLONG_MAX)
176156a1485bSTali Perry 			bus->rec_fail_cnt++;
176256a1485bSTali Perry 	} else {
176356a1485bSTali Perry 		if (bus->rec_succ_cnt < ULLONG_MAX)
176456a1485bSTali Perry 			bus->rec_succ_cnt++;
176556a1485bSTali Perry 	}
176656a1485bSTali Perry 	return status;
176756a1485bSTali Perry }
176856a1485bSTali Perry 
176956a1485bSTali Perry /* recovery using bit banging functionality of the module */
177056a1485bSTali Perry static void npcm_i2c_recovery_init(struct i2c_adapter *_adap)
177156a1485bSTali Perry {
177256a1485bSTali Perry 	struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
177356a1485bSTali Perry 	struct i2c_bus_recovery_info *rinfo = &bus->rinfo;
177456a1485bSTali Perry 
177556a1485bSTali Perry 	rinfo->recover_bus = npcm_i2c_recovery_tgclk;
177656a1485bSTali Perry 
177756a1485bSTali Perry 	/*
177856a1485bSTali Perry 	 * npcm i2c HW allows direct reading of SCL and SDA.
177956a1485bSTali Perry 	 * However, it does not support setting SCL and SDA directly.
17800c47dd7dSJonathan Neuschäfer 	 * The recovery function can toggle SCL when SDA is low (but not set)
17810c47dd7dSJonathan Neuschäfer 	 * Getter functions used internally, and can be used externally.
178256a1485bSTali Perry 	 */
178356a1485bSTali Perry 	rinfo->get_scl = npcm_i2c_get_SCL;
178456a1485bSTali Perry 	rinfo->get_sda = npcm_i2c_get_SDA;
178556a1485bSTali Perry 	_adap->bus_recovery_info = rinfo;
178656a1485bSTali Perry }
178756a1485bSTali Perry 
178856a1485bSTali Perry /* SCLFRQ min/max field values */
178956a1485bSTali Perry #define SCLFRQ_MIN  10
179056a1485bSTali Perry #define SCLFRQ_MAX  511
179156a1485bSTali Perry #define clk_coef(freq, mul)	DIV_ROUND_UP((freq) * (mul), 1000000)
179256a1485bSTali Perry 
179356a1485bSTali Perry /*
179456a1485bSTali Perry  * npcm_i2c_init_clk: init HW timing parameters.
17950c47dd7dSJonathan Neuschäfer  * NPCM7XX i2c module timing parameters are dependent on module core clk (APB)
179656a1485bSTali Perry  * and bus frequency.
17970c47dd7dSJonathan Neuschäfer  * 100kHz bus requires tSCL = 4 * SCLFRQ * tCLK. LT and HT are symmetric.
17980c47dd7dSJonathan Neuschäfer  * 400kHz bus requires asymmetric HT and LT. A different equation is recommended
179956a1485bSTali Perry  * by the HW designer, given core clock range (equations in comments below).
180056a1485bSTali Perry  *
180156a1485bSTali Perry  */
180256a1485bSTali Perry static int npcm_i2c_init_clk(struct npcm_i2c *bus, u32 bus_freq_hz)
180356a1485bSTali Perry {
180456a1485bSTali Perry 	u32  k1 = 0;
180556a1485bSTali Perry 	u32  k2 = 0;
180656a1485bSTali Perry 	u8   dbnct = 0;
180756a1485bSTali Perry 	u32  sclfrq = 0;
180856a1485bSTali Perry 	u8   hldt = 7;
180956a1485bSTali Perry 	u8   fast_mode = 0;
181056a1485bSTali Perry 	u32  src_clk_khz;
181156a1485bSTali Perry 	u32  bus_freq_khz;
181256a1485bSTali Perry 
181356a1485bSTali Perry 	src_clk_khz = bus->apb_clk / 1000;
181456a1485bSTali Perry 	bus_freq_khz = bus_freq_hz / 1000;
181556a1485bSTali Perry 	bus->bus_freq = bus_freq_hz;
181656a1485bSTali Perry 
181756a1485bSTali Perry 	/* 100KHz and below: */
181856a1485bSTali Perry 	if (bus_freq_hz <= I2C_MAX_STANDARD_MODE_FREQ) {
181956a1485bSTali Perry 		sclfrq = src_clk_khz / (bus_freq_khz * 4);
182056a1485bSTali Perry 
182156a1485bSTali Perry 		if (sclfrq < SCLFRQ_MIN || sclfrq > SCLFRQ_MAX)
182256a1485bSTali Perry 			return -EDOM;
182356a1485bSTali Perry 
182456a1485bSTali Perry 		if (src_clk_khz >= 40000)
182556a1485bSTali Perry 			hldt = 17;
182656a1485bSTali Perry 		else if (src_clk_khz >= 12500)
182756a1485bSTali Perry 			hldt = 15;
182856a1485bSTali Perry 		else
182956a1485bSTali Perry 			hldt = 7;
183056a1485bSTali Perry 	}
183156a1485bSTali Perry 
183256a1485bSTali Perry 	/* 400KHz: */
183356a1485bSTali Perry 	else if (bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ) {
183456a1485bSTali Perry 		sclfrq = 0;
183556a1485bSTali Perry 		fast_mode = I2CCTL3_400K_MODE;
183656a1485bSTali Perry 
183756a1485bSTali Perry 		if (src_clk_khz < 7500)
183856a1485bSTali Perry 			/* 400KHZ cannot be supported for core clock < 7.5MHz */
183956a1485bSTali Perry 			return -EDOM;
184056a1485bSTali Perry 
184156a1485bSTali Perry 		else if (src_clk_khz >= 50000) {
184256a1485bSTali Perry 			k1 = 80;
184356a1485bSTali Perry 			k2 = 48;
184456a1485bSTali Perry 			hldt = 12;
184556a1485bSTali Perry 			dbnct = 7;
184656a1485bSTali Perry 		}
184756a1485bSTali Perry 
184856a1485bSTali Perry 		/* Master or Slave with frequency > 25MHz */
184956a1485bSTali Perry 		else if (src_clk_khz > 25000) {
185056a1485bSTali Perry 			hldt = clk_coef(src_clk_khz, 300) + 7;
185156a1485bSTali Perry 			k1 = clk_coef(src_clk_khz, 1600);
185256a1485bSTali Perry 			k2 = clk_coef(src_clk_khz, 900);
185356a1485bSTali Perry 		}
185456a1485bSTali Perry 	}
185556a1485bSTali Perry 
185656a1485bSTali Perry 	/* 1MHz: */
185756a1485bSTali Perry 	else if (bus_freq_hz <= I2C_MAX_FAST_MODE_PLUS_FREQ) {
185856a1485bSTali Perry 		sclfrq = 0;
185956a1485bSTali Perry 		fast_mode = I2CCTL3_400K_MODE;
186056a1485bSTali Perry 
186156a1485bSTali Perry 		/* 1MHZ cannot be supported for core clock < 24 MHz */
186256a1485bSTali Perry 		if (src_clk_khz < 24000)
186356a1485bSTali Perry 			return -EDOM;
186456a1485bSTali Perry 
186556a1485bSTali Perry 		k1 = clk_coef(src_clk_khz, 620);
186656a1485bSTali Perry 		k2 = clk_coef(src_clk_khz, 380);
186756a1485bSTali Perry 
186856a1485bSTali Perry 		/* Core clk > 40 MHz */
186956a1485bSTali Perry 		if (src_clk_khz > 40000) {
187056a1485bSTali Perry 			/*
187156a1485bSTali Perry 			 * Set HLDT:
187256a1485bSTali Perry 			 * SDA hold time:  (HLDT-7) * T(CLK) >= 120
187356a1485bSTali Perry 			 * HLDT = 120/T(CLK) + 7 = 120 * FREQ(CLK) + 7
187456a1485bSTali Perry 			 */
187556a1485bSTali Perry 			hldt = clk_coef(src_clk_khz, 120) + 7;
187656a1485bSTali Perry 		} else {
187756a1485bSTali Perry 			hldt = 7;
187856a1485bSTali Perry 			dbnct = 2;
187956a1485bSTali Perry 		}
188056a1485bSTali Perry 	}
188156a1485bSTali Perry 
188256a1485bSTali Perry 	/* Frequency larger than 1 MHz is not supported */
188356a1485bSTali Perry 	else
188456a1485bSTali Perry 		return -EINVAL;
188556a1485bSTali Perry 
188656a1485bSTali Perry 	if (bus_freq_hz >= I2C_MAX_FAST_MODE_FREQ) {
188756a1485bSTali Perry 		k1 = round_up(k1, 2);
188856a1485bSTali Perry 		k2 = round_up(k2 + 1, 2);
188956a1485bSTali Perry 		if (k1 < SCLFRQ_MIN || k1 > SCLFRQ_MAX ||
189056a1485bSTali Perry 		    k2 < SCLFRQ_MIN || k2 > SCLFRQ_MAX)
189156a1485bSTali Perry 			return -EDOM;
189256a1485bSTali Perry 	}
189356a1485bSTali Perry 
189456a1485bSTali Perry 	/* write sclfrq value. bits [6:0] are in I2CCTL2 reg */
189556a1485bSTali Perry 	iowrite8(FIELD_PREP(I2CCTL2_SCLFRQ6_0, sclfrq & 0x7F),
189656a1485bSTali Perry 		 bus->reg + NPCM_I2CCTL2);
189756a1485bSTali Perry 
189856a1485bSTali Perry 	/* bits [8:7] are in I2CCTL3 reg */
189956a1485bSTali Perry 	iowrite8(fast_mode | FIELD_PREP(I2CCTL3_SCLFRQ8_7, (sclfrq >> 7) & 0x3),
190056a1485bSTali Perry 		 bus->reg + NPCM_I2CCTL3);
190156a1485bSTali Perry 
190256a1485bSTali Perry 	/* Select Bank 0 to access NPCM_I2CCTL4/NPCM_I2CCTL5 */
190356a1485bSTali Perry 	npcm_i2c_select_bank(bus, I2C_BANK_0);
190456a1485bSTali Perry 
190556a1485bSTali Perry 	if (bus_freq_hz >= I2C_MAX_FAST_MODE_FREQ) {
190656a1485bSTali Perry 		/*
190756a1485bSTali Perry 		 * Set SCL Low/High Time:
190856a1485bSTali Perry 		 * k1 = 2 * SCLLT7-0 -> Low Time  = k1 / 2
190956a1485bSTali Perry 		 * k2 = 2 * SCLLT7-0 -> High Time = k2 / 2
191056a1485bSTali Perry 		 */
191156a1485bSTali Perry 		iowrite8(k1 / 2, bus->reg + NPCM_I2CSCLLT);
191256a1485bSTali Perry 		iowrite8(k2 / 2, bus->reg + NPCM_I2CSCLHT);
191356a1485bSTali Perry 
191456a1485bSTali Perry 		iowrite8(dbnct, bus->reg + NPCM_I2CCTL5);
191556a1485bSTali Perry 	}
191656a1485bSTali Perry 
191756a1485bSTali Perry 	iowrite8(hldt, bus->reg + NPCM_I2CCTL4);
191856a1485bSTali Perry 
191956a1485bSTali Perry 	/* Return to Bank 1, and stay there by default: */
192056a1485bSTali Perry 	npcm_i2c_select_bank(bus, I2C_BANK_1);
192156a1485bSTali Perry 
192256a1485bSTali Perry 	return 0;
192356a1485bSTali Perry }
192456a1485bSTali Perry 
192556a1485bSTali Perry static int npcm_i2c_init_module(struct npcm_i2c *bus, enum i2c_mode mode,
192656a1485bSTali Perry 				u32 bus_freq_hz)
192756a1485bSTali Perry {
192856a1485bSTali Perry 	u8 val;
192956a1485bSTali Perry 	int ret;
193056a1485bSTali Perry 
193156a1485bSTali Perry 	/* Check whether module already enabled or frequency is out of bounds */
193256a1485bSTali Perry 	if ((bus->state != I2C_DISABLE && bus->state != I2C_IDLE) ||
193356a1485bSTali Perry 	    bus_freq_hz < I2C_FREQ_MIN_HZ || bus_freq_hz > I2C_FREQ_MAX_HZ)
193456a1485bSTali Perry 		return -EINVAL;
193556a1485bSTali Perry 
1936e5222d40STali Perry 	npcm_i2c_int_enable(bus, false);
193756a1485bSTali Perry 	npcm_i2c_disable(bus);
193856a1485bSTali Perry 
193956a1485bSTali Perry 	/* Configure FIFO mode : */
194056a1485bSTali Perry 	if (FIELD_GET(I2C_VER_FIFO_EN, ioread8(bus->reg + I2C_VER))) {
194156a1485bSTali Perry 		bus->fifo_use = true;
194256a1485bSTali Perry 		npcm_i2c_select_bank(bus, I2C_BANK_0);
194356a1485bSTali Perry 		val = ioread8(bus->reg + NPCM_I2CFIF_CTL);
194456a1485bSTali Perry 		val |= NPCM_I2CFIF_CTL_FIFO_EN;
194556a1485bSTali Perry 		iowrite8(val, bus->reg + NPCM_I2CFIF_CTL);
194656a1485bSTali Perry 		npcm_i2c_select_bank(bus, I2C_BANK_1);
194756a1485bSTali Perry 	} else {
194856a1485bSTali Perry 		bus->fifo_use = false;
194956a1485bSTali Perry 	}
195056a1485bSTali Perry 
195156a1485bSTali Perry 	/* Configure I2C module clock frequency */
195256a1485bSTali Perry 	ret = npcm_i2c_init_clk(bus, bus_freq_hz);
195356a1485bSTali Perry 	if (ret) {
195456a1485bSTali Perry 		dev_err(bus->dev, "npcm_i2c_init_clk failed\n");
195556a1485bSTali Perry 		return ret;
195656a1485bSTali Perry 	}
195756a1485bSTali Perry 
195856a1485bSTali Perry 	/* Enable module (before configuring CTL1) */
195956a1485bSTali Perry 	npcm_i2c_enable(bus);
196056a1485bSTali Perry 	bus->state = I2C_IDLE;
196156a1485bSTali Perry 	val = ioread8(bus->reg + NPCM_I2CCTL1);
196256a1485bSTali Perry 	val = (val | NPCM_I2CCTL1_NMINTE) & ~NPCM_I2CCTL1_RWS;
196356a1485bSTali Perry 	iowrite8(val, bus->reg + NPCM_I2CCTL1);
196456a1485bSTali Perry 
196556a1485bSTali Perry 	npcm_i2c_reset(bus);
196656a1485bSTali Perry 
1967ffad0a35STyrone Ting 	/* Check HW is OK: SDA and SCL should be high at this point. */
1968e5222d40STali Perry 	if ((npcm_i2c_get_SDA(&bus->adap) == 0) || (npcm_i2c_get_SCL(&bus->adap) == 0)) {
1969e5222d40STali Perry 		dev_err(bus->dev, "I2C%d init fail: lines are low\n", bus->num);
1970e5222d40STali Perry 		dev_err(bus->dev, "SDA=%d SCL=%d\n", npcm_i2c_get_SDA(&bus->adap),
1971e5222d40STali Perry 			npcm_i2c_get_SCL(&bus->adap));
1972e5222d40STali Perry 		return -ENXIO;
1973e5222d40STali Perry 	}
1974e5222d40STali Perry 
1975e5222d40STali Perry 	npcm_i2c_int_enable(bus, true);
197656a1485bSTali Perry 	return 0;
197756a1485bSTali Perry }
197856a1485bSTali Perry 
197956a1485bSTali Perry static int __npcm_i2c_init(struct npcm_i2c *bus, struct platform_device *pdev)
198056a1485bSTali Perry {
198156a1485bSTali Perry 	u32 clk_freq_hz;
198256a1485bSTali Perry 	int ret;
198356a1485bSTali Perry 
198456a1485bSTali Perry 	/* Initialize the internal data structures */
198556a1485bSTali Perry 	bus->state = I2C_DISABLE;
198656a1485bSTali Perry 	bus->master_or_slave = I2C_SLAVE;
198756a1485bSTali Perry 	bus->int_time_stamp = 0;
1988f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
1989f5473692STali Perry 	bus->slave = NULL;
1990f5473692STali Perry #endif
199156a1485bSTali Perry 
199256a1485bSTali Perry 	ret = device_property_read_u32(&pdev->dev, "clock-frequency",
199356a1485bSTali Perry 				       &clk_freq_hz);
199456a1485bSTali Perry 	if (ret) {
199556a1485bSTali Perry 		dev_info(&pdev->dev, "Could not read clock-frequency property");
199656a1485bSTali Perry 		clk_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
199756a1485bSTali Perry 	}
199856a1485bSTali Perry 
199956a1485bSTali Perry 	ret = npcm_i2c_init_module(bus, I2C_MASTER, clk_freq_hz);
200056a1485bSTali Perry 	if (ret) {
200156a1485bSTali Perry 		dev_err(&pdev->dev, "npcm_i2c_init_module failed\n");
200256a1485bSTali Perry 		return ret;
200356a1485bSTali Perry 	}
200456a1485bSTali Perry 
200556a1485bSTali Perry 	return 0;
200656a1485bSTali Perry }
200756a1485bSTali Perry 
200856a1485bSTali Perry static irqreturn_t npcm_i2c_bus_irq(int irq, void *dev_id)
200956a1485bSTali Perry {
201056a1485bSTali Perry 	struct npcm_i2c *bus = dev_id;
201156a1485bSTali Perry 
201256a1485bSTali Perry 	if (npcm_i2c_is_master(bus))
201356a1485bSTali Perry 		bus->master_or_slave = I2C_MASTER;
201456a1485bSTali Perry 
201556a1485bSTali Perry 	if (bus->master_or_slave == I2C_MASTER) {
201656a1485bSTali Perry 		bus->int_time_stamp = jiffies;
201756a1485bSTali Perry 		if (!npcm_i2c_int_master_handler(bus))
201856a1485bSTali Perry 			return IRQ_HANDLED;
201956a1485bSTali Perry 	}
2020f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
2021f5473692STali Perry 	if (bus->slave) {
2022f5473692STali Perry 		bus->master_or_slave = I2C_SLAVE;
2023e5222d40STali Perry 		if (npcm_i2c_int_slave_handler(bus))
2024e5222d40STali Perry 			return IRQ_HANDLED;
2025f5473692STali Perry 	}
2026f5473692STali Perry #endif
2027ffad0a35STyrone Ting 	/* Clear status bits for spurious interrupts */
2028e5222d40STali Perry 	npcm_i2c_clear_master_status(bus);
2029e5222d40STali Perry 
2030e5222d40STali Perry 	return IRQ_HANDLED;
203156a1485bSTali Perry }
203256a1485bSTali Perry 
203356a1485bSTali Perry static bool npcm_i2c_master_start_xmit(struct npcm_i2c *bus,
203456a1485bSTali Perry 				       u8 slave_addr, u16 nwrite, u16 nread,
203556a1485bSTali Perry 				       u8 *write_data, u8 *read_data,
203656a1485bSTali Perry 				       bool use_PEC, bool use_read_block)
203756a1485bSTali Perry {
203856a1485bSTali Perry 	if (bus->state != I2C_IDLE) {
203956a1485bSTali Perry 		bus->cmd_err = -EBUSY;
204056a1485bSTali Perry 		return false;
204156a1485bSTali Perry 	}
204256a1485bSTali Perry 	bus->dest_addr = slave_addr << 1;
204356a1485bSTali Perry 	bus->wr_buf = write_data;
204456a1485bSTali Perry 	bus->wr_size = nwrite;
204556a1485bSTali Perry 	bus->wr_ind = 0;
204656a1485bSTali Perry 	bus->rd_buf = read_data;
204756a1485bSTali Perry 	bus->rd_size = nread;
204856a1485bSTali Perry 	bus->rd_ind = 0;
204956a1485bSTali Perry 	bus->PEC_use = 0;
205056a1485bSTali Perry 
205156a1485bSTali Perry 	/* for tx PEC is appended to buffer from i2c IF. PEC flag is ignored */
205256a1485bSTali Perry 	if (nread)
205356a1485bSTali Perry 		bus->PEC_use = use_PEC;
205456a1485bSTali Perry 
205556a1485bSTali Perry 	bus->read_block_use = use_read_block;
205656a1485bSTali Perry 	if (nread && !nwrite)
205756a1485bSTali Perry 		bus->operation = I2C_READ_OPER;
205856a1485bSTali Perry 	else
205956a1485bSTali Perry 		bus->operation = I2C_WRITE_OPER;
206056a1485bSTali Perry 	if (bus->fifo_use) {
206156a1485bSTali Perry 		u8 i2cfif_cts;
206256a1485bSTali Perry 
206356a1485bSTali Perry 		npcm_i2c_select_bank(bus, I2C_BANK_1);
206456a1485bSTali Perry 		/* clear FIFO and relevant status bits. */
206556a1485bSTali Perry 		i2cfif_cts = ioread8(bus->reg + NPCM_I2CFIF_CTS);
206656a1485bSTali Perry 		i2cfif_cts &= ~NPCM_I2CFIF_CTS_SLVRSTR;
206756a1485bSTali Perry 		i2cfif_cts |= NPCM_I2CFIF_CTS_CLR_FIFO;
206856a1485bSTali Perry 		iowrite8(i2cfif_cts, bus->reg + NPCM_I2CFIF_CTS);
206956a1485bSTali Perry 	}
207056a1485bSTali Perry 
207156a1485bSTali Perry 	bus->state = I2C_IDLE;
207256a1485bSTali Perry 	npcm_i2c_stall_after_start(bus, true);
207356a1485bSTali Perry 	npcm_i2c_master_start(bus);
207456a1485bSTali Perry 	return true;
207556a1485bSTali Perry }
207656a1485bSTali Perry 
207756a1485bSTali Perry static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
207856a1485bSTali Perry 				int num)
207956a1485bSTali Perry {
208056a1485bSTali Perry 	struct npcm_i2c *bus = container_of(adap, struct npcm_i2c, adap);
208156a1485bSTali Perry 	struct i2c_msg *msg0, *msg1;
208256a1485bSTali Perry 	unsigned long time_left, flags;
208356a1485bSTali Perry 	u16 nwrite, nread;
208456a1485bSTali Perry 	u8 *write_data, *read_data;
208556a1485bSTali Perry 	u8 slave_addr;
2086288b2044STali Perry 	unsigned long timeout;
208756a1485bSTali Perry 	bool read_block = false;
208856a1485bSTali Perry 	bool read_PEC = false;
208956a1485bSTali Perry 	u8 bus_busy;
209056a1485bSTali Perry 	unsigned long timeout_usec;
209156a1485bSTali Perry 
209256a1485bSTali Perry 	if (bus->state == I2C_DISABLE) {
209356a1485bSTali Perry 		dev_err(bus->dev, "I2C%d module is disabled", bus->num);
209456a1485bSTali Perry 		return -EINVAL;
209556a1485bSTali Perry 	}
209656a1485bSTali Perry 
209756a1485bSTali Perry 	msg0 = &msgs[0];
209856a1485bSTali Perry 	slave_addr = msg0->addr;
209956a1485bSTali Perry 	if (msg0->flags & I2C_M_RD) { /* read */
210056a1485bSTali Perry 		nwrite = 0;
210156a1485bSTali Perry 		write_data = NULL;
210256a1485bSTali Perry 		read_data = msg0->buf;
210356a1485bSTali Perry 		if (msg0->flags & I2C_M_RECV_LEN) {
210456a1485bSTali Perry 			nread = 1;
210556a1485bSTali Perry 			read_block = true;
210656a1485bSTali Perry 			if (msg0->flags & I2C_CLIENT_PEC)
210756a1485bSTali Perry 				read_PEC = true;
210856a1485bSTali Perry 		} else {
210956a1485bSTali Perry 			nread = msg0->len;
211056a1485bSTali Perry 		}
211156a1485bSTali Perry 	} else { /* write */
211256a1485bSTali Perry 		nwrite = msg0->len;
211356a1485bSTali Perry 		write_data = msg0->buf;
211456a1485bSTali Perry 		nread = 0;
211556a1485bSTali Perry 		read_data = NULL;
211656a1485bSTali Perry 		if (num == 2) {
211756a1485bSTali Perry 			msg1 = &msgs[1];
211856a1485bSTali Perry 			read_data = msg1->buf;
211956a1485bSTali Perry 			if (msg1->flags & I2C_M_RECV_LEN) {
212056a1485bSTali Perry 				nread = 1;
212156a1485bSTali Perry 				read_block = true;
212256a1485bSTali Perry 				if (msg1->flags & I2C_CLIENT_PEC)
212356a1485bSTali Perry 					read_PEC = true;
212456a1485bSTali Perry 			} else {
212556a1485bSTali Perry 				nread = msg1->len;
212656a1485bSTali Perry 				read_block = false;
212756a1485bSTali Perry 			}
212856a1485bSTali Perry 		}
212956a1485bSTali Perry 	}
213056a1485bSTali Perry 
213106be6726STali Perry 	/*
213206be6726STali Perry 	 * Adaptive TimeOut: estimated time in usec + 100% margin:
213306be6726STali Perry 	 * 2: double the timeout for clock stretching case
213406be6726STali Perry 	 * 9: bits per transaction (including the ack/nack)
213506be6726STali Perry 	 */
213606be6726STali Perry 	timeout_usec = (2 * 9 * USEC_PER_SEC / bus->bus_freq) * (2 + nread + nwrite);
2137288b2044STali Perry 	timeout = max_t(unsigned long, bus->adap.timeout, usecs_to_jiffies(timeout_usec));
213856a1485bSTali Perry 	if (nwrite >= 32 * 1024 || nread >= 32 * 1024) {
213956a1485bSTali Perry 		dev_err(bus->dev, "i2c%d buffer too big\n", bus->num);
214056a1485bSTali Perry 		return -EINVAL;
214156a1485bSTali Perry 	}
214256a1485bSTali Perry 
2143288b2044STali Perry 	time_left = jiffies + timeout + 1;
214456a1485bSTali Perry 	do {
214556a1485bSTali Perry 		/*
214656a1485bSTali Perry 		 * we must clear slave address immediately when the bus is not
214756a1485bSTali Perry 		 * busy, so we spinlock it, but we don't keep the lock for the
214856a1485bSTali Perry 		 * entire while since it is too long.
214956a1485bSTali Perry 		 */
215056a1485bSTali Perry 		spin_lock_irqsave(&bus->lock, flags);
215156a1485bSTali Perry 		bus_busy = ioread8(bus->reg + NPCM_I2CCST) & NPCM_I2CCST_BB;
2152f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
2153f5473692STali Perry 		if (!bus_busy && bus->slave)
2154f5473692STali Perry 			iowrite8((bus->slave->addr & 0x7F),
2155f5473692STali Perry 				 bus->reg + NPCM_I2CADDR1);
2156f5473692STali Perry #endif
215756a1485bSTali Perry 		spin_unlock_irqrestore(&bus->lock, flags);
215856a1485bSTali Perry 
215956a1485bSTali Perry 	} while (time_is_after_jiffies(time_left) && bus_busy);
216056a1485bSTali Perry 
216156a1485bSTali Perry 	if (bus_busy) {
216256a1485bSTali Perry 		iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
216356a1485bSTali Perry 		npcm_i2c_reset(bus);
216456a1485bSTali Perry 		i2c_recover_bus(adap);
216556a1485bSTali Perry 		return -EAGAIN;
216656a1485bSTali Perry 	}
216756a1485bSTali Perry 
216856a1485bSTali Perry 	npcm_i2c_init_params(bus);
216956a1485bSTali Perry 	bus->dest_addr = slave_addr;
217056a1485bSTali Perry 	bus->msgs = msgs;
217156a1485bSTali Perry 	bus->msgs_num = num;
217256a1485bSTali Perry 	bus->cmd_err = 0;
217356a1485bSTali Perry 	bus->read_block_use = read_block;
217456a1485bSTali Perry 
217556a1485bSTali Perry 	reinit_completion(&bus->cmd_complete);
217656a1485bSTali Perry 
2177e5222d40STali Perry 	npcm_i2c_int_enable(bus, true);
2178e5222d40STali Perry 
2179e5222d40STali Perry 	if (npcm_i2c_master_start_xmit(bus, slave_addr, nwrite, nread,
2180e5222d40STali Perry 				       write_data, read_data, read_PEC,
2181e5222d40STali Perry 				       read_block)) {
218256a1485bSTali Perry 		time_left = wait_for_completion_timeout(&bus->cmd_complete,
218356a1485bSTali Perry 							timeout);
218456a1485bSTali Perry 
218556a1485bSTali Perry 		if (time_left == 0) {
218656a1485bSTali Perry 			if (bus->timeout_cnt < ULLONG_MAX)
218756a1485bSTali Perry 				bus->timeout_cnt++;
218856a1485bSTali Perry 			if (bus->master_or_slave == I2C_MASTER) {
218956a1485bSTali Perry 				i2c_recover_bus(adap);
219056a1485bSTali Perry 				bus->cmd_err = -EIO;
219156a1485bSTali Perry 				bus->state = I2C_IDLE;
219256a1485bSTali Perry 			}
219356a1485bSTali Perry 		}
219456a1485bSTali Perry 	}
219556a1485bSTali Perry 
219656a1485bSTali Perry 	/* if there was BER, check if need to recover the bus: */
219756a1485bSTali Perry 	if (bus->cmd_err == -EAGAIN)
2198e5222d40STali Perry 		bus->cmd_err = i2c_recover_bus(adap);
219956a1485bSTali Perry 
22008947efc0STali Perry 	/*
22018947efc0STali Perry 	 * After any type of error, check if LAST bit is still set,
22028947efc0STali Perry 	 * due to a HW issue.
22038947efc0STali Perry 	 * It cannot be cleared without resetting the module.
22048947efc0STali Perry 	 */
2205e5222d40STali Perry 	else if (bus->cmd_err &&
2206bbc38ed5STyrone Ting 		 (bus->data->rxf_ctl_last_pec & ioread8(bus->reg + NPCM_I2CRXF_CTL)))
22078947efc0STali Perry 		npcm_i2c_reset(bus);
22088947efc0STali Perry 
2209ffad0a35STyrone Ting 	/* After any xfer, successful or not, stall and EOB must be disabled */
2210e5222d40STali Perry 	npcm_i2c_stall_after_start(bus, false);
2211e5222d40STali Perry 	npcm_i2c_eob_int(bus, false);
2212e5222d40STali Perry 
2213f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
2214f5473692STali Perry 	/* reenable slave if it was enabled */
2215f5473692STali Perry 	if (bus->slave)
2216f5473692STali Perry 		iowrite8((bus->slave->addr & 0x7F) | NPCM_I2CADDR_SAEN,
2217f5473692STali Perry 			 bus->reg + NPCM_I2CADDR1);
2218e5222d40STali Perry #else
2219e5222d40STali Perry 	npcm_i2c_int_enable(bus, false);
2220f5473692STali Perry #endif
222156a1485bSTali Perry 	return bus->cmd_err;
222256a1485bSTali Perry }
222356a1485bSTali Perry 
222456a1485bSTali Perry static u32 npcm_i2c_functionality(struct i2c_adapter *adap)
222556a1485bSTali Perry {
222656a1485bSTali Perry 	return I2C_FUNC_I2C |
222756a1485bSTali Perry 	       I2C_FUNC_SMBUS_EMUL |
222856a1485bSTali Perry 	       I2C_FUNC_SMBUS_BLOCK_DATA |
2229f5473692STali Perry 	       I2C_FUNC_SMBUS_PEC |
2230f5473692STali Perry 	       I2C_FUNC_SLAVE;
223156a1485bSTali Perry }
223256a1485bSTali Perry 
223356a1485bSTali Perry static const struct i2c_adapter_quirks npcm_i2c_quirks = {
223456a1485bSTali Perry 	.max_read_len = 32768,
223556a1485bSTali Perry 	.max_write_len = 32768,
223656a1485bSTali Perry 	.flags = I2C_AQ_COMB_WRITE_THEN_READ,
223756a1485bSTali Perry };
223856a1485bSTali Perry 
223956a1485bSTali Perry static const struct i2c_algorithm npcm_i2c_algo = {
224056a1485bSTali Perry 	.master_xfer = npcm_i2c_master_xfer,
224156a1485bSTali Perry 	.functionality = npcm_i2c_functionality,
2242f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
2243f5473692STali Perry 	.reg_slave	= npcm_i2c_reg_slave,
2244f5473692STali Perry 	.unreg_slave	= npcm_i2c_unreg_slave,
2245f5473692STali Perry #endif
224656a1485bSTali Perry };
224756a1485bSTali Perry 
224856a1485bSTali Perry static void npcm_i2c_init_debugfs(struct platform_device *pdev,
224956a1485bSTali Perry 				  struct npcm_i2c *bus)
225056a1485bSTali Perry {
2251e19e1abcSWolfram Sang 	debugfs_create_u64("ber_cnt", 0444, bus->adap.debugfs, &bus->ber_cnt);
2252e19e1abcSWolfram Sang 	debugfs_create_u64("nack_cnt", 0444, bus->adap.debugfs, &bus->nack_cnt);
2253e19e1abcSWolfram Sang 	debugfs_create_u64("rec_succ_cnt", 0444, bus->adap.debugfs, &bus->rec_succ_cnt);
2254e19e1abcSWolfram Sang 	debugfs_create_u64("rec_fail_cnt", 0444, bus->adap.debugfs, &bus->rec_fail_cnt);
2255e19e1abcSWolfram Sang 	debugfs_create_u64("timeout_cnt", 0444, bus->adap.debugfs, &bus->timeout_cnt);
2256e19e1abcSWolfram Sang 	debugfs_create_u64("tx_complete_cnt", 0444, bus->adap.debugfs, &bus->tx_complete_cnt);
225756a1485bSTali Perry }
225856a1485bSTali Perry 
225956a1485bSTali Perry static int npcm_i2c_probe_bus(struct platform_device *pdev)
226056a1485bSTali Perry {
22610585c1d2STali Perry 	struct device_node *np = pdev->dev.of_node;
226256a1485bSTali Perry 	static struct regmap *gcr_regmap;
2263bbc38ed5STyrone Ting 	struct device *dev = &pdev->dev;
22640585c1d2STali Perry 	struct i2c_adapter *adap;
22650585c1d2STali Perry 	struct npcm_i2c *bus;
22660585c1d2STali Perry 	struct clk *i2c_clk;
226756a1485bSTali Perry 	int irq;
226856a1485bSTali Perry 	int ret;
226956a1485bSTali Perry 
227056a1485bSTali Perry 	bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
227156a1485bSTali Perry 	if (!bus)
227256a1485bSTali Perry 		return -ENOMEM;
227356a1485bSTali Perry 
227456a1485bSTali Perry 	bus->dev = &pdev->dev;
227556a1485bSTali Perry 
2276bbc38ed5STyrone Ting 	bus->data = of_device_get_match_data(dev);
2277bbc38ed5STyrone Ting 	if (!bus->data) {
2278bbc38ed5STyrone Ting 		dev_err(dev, "OF data missing\n");
2279bbc38ed5STyrone Ting 		return -EINVAL;
2280bbc38ed5STyrone Ting 	}
2281bbc38ed5STyrone Ting 
228256a1485bSTali Perry 	bus->num = of_alias_get_id(pdev->dev.of_node, "i2c");
228356a1485bSTali Perry 	/* core clk must be acquired to calculate module timing settings */
228456a1485bSTali Perry 	i2c_clk = devm_clk_get(&pdev->dev, NULL);
228556a1485bSTali Perry 	if (IS_ERR(i2c_clk))
228656a1485bSTali Perry 		return PTR_ERR(i2c_clk);
228756a1485bSTali Perry 	bus->apb_clk = clk_get_rate(i2c_clk);
228856a1485bSTali Perry 
22890585c1d2STali Perry 	gcr_regmap = syscon_regmap_lookup_by_phandle(np, "nuvoton,sys-mgr");
22900585c1d2STali Perry 	if (IS_ERR(gcr_regmap))
229156a1485bSTali Perry 		gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
22920585c1d2STali Perry 
229356a1485bSTali Perry 	if (IS_ERR(gcr_regmap))
2294de9be772SDan Carpenter 		return PTR_ERR(gcr_regmap);
2295bbc38ed5STyrone Ting 	regmap_write(gcr_regmap, NPCM_I2CSEGCTL, bus->data->segctl_init_val);
229656a1485bSTali Perry 
229756a1485bSTali Perry 	bus->reg = devm_platform_ioremap_resource(pdev, 0);
229856a1485bSTali Perry 	if (IS_ERR(bus->reg))
22992667a681SGustavo A. R. Silva 		return PTR_ERR(bus->reg);
230056a1485bSTali Perry 
230156a1485bSTali Perry 	spin_lock_init(&bus->lock);
230256a1485bSTali Perry 	init_completion(&bus->cmd_complete);
230356a1485bSTali Perry 
230456a1485bSTali Perry 	adap = &bus->adap;
230556a1485bSTali Perry 	adap->owner = THIS_MODULE;
230656a1485bSTali Perry 	adap->retries = 3;
2307288b2044STali Perry 	adap->timeout = msecs_to_jiffies(35);
230856a1485bSTali Perry 	adap->algo = &npcm_i2c_algo;
230956a1485bSTali Perry 	adap->quirks = &npcm_i2c_quirks;
231056a1485bSTali Perry 	adap->algo_data = bus;
231156a1485bSTali Perry 	adap->dev.parent = &pdev->dev;
231256a1485bSTali Perry 	adap->dev.of_node = pdev->dev.of_node;
231356a1485bSTali Perry 	adap->nr = pdev->id;
231456a1485bSTali Perry 
231556a1485bSTali Perry 	irq = platform_get_irq(pdev, 0);
231656a1485bSTali Perry 	if (irq < 0)
231756a1485bSTali Perry 		return irq;
231856a1485bSTali Perry 
231956a1485bSTali Perry 	ret = devm_request_irq(bus->dev, irq, npcm_i2c_bus_irq, 0,
232056a1485bSTali Perry 			       dev_name(bus->dev), bus);
232156a1485bSTali Perry 	if (ret)
232256a1485bSTali Perry 		return ret;
232356a1485bSTali Perry 
232456a1485bSTali Perry 	ret = __npcm_i2c_init(bus, pdev);
232556a1485bSTali Perry 	if (ret)
232656a1485bSTali Perry 		return ret;
232756a1485bSTali Perry 
232856a1485bSTali Perry 	npcm_i2c_recovery_init(adap);
232956a1485bSTali Perry 
233056a1485bSTali Perry 	i2c_set_adapdata(adap, bus);
233156a1485bSTali Perry 
233256a1485bSTali Perry 	snprintf(bus->adap.name, sizeof(bus->adap.name), "npcm_i2c_%d",
233356a1485bSTali Perry 		 bus->num);
233456a1485bSTali Perry 	ret = i2c_add_numbered_adapter(&bus->adap);
233556a1485bSTali Perry 	if (ret)
233656a1485bSTali Perry 		return ret;
233756a1485bSTali Perry 
233856a1485bSTali Perry 	platform_set_drvdata(pdev, bus);
233956a1485bSTali Perry 	npcm_i2c_init_debugfs(pdev, bus);
234056a1485bSTali Perry 	return 0;
234156a1485bSTali Perry }
234256a1485bSTali Perry 
2343e190a0c3SUwe Kleine-König static void npcm_i2c_remove_bus(struct platform_device *pdev)
234456a1485bSTali Perry {
234556a1485bSTali Perry 	unsigned long lock_flags;
234656a1485bSTali Perry 	struct npcm_i2c *bus = platform_get_drvdata(pdev);
234756a1485bSTali Perry 
234856a1485bSTali Perry 	spin_lock_irqsave(&bus->lock, lock_flags);
234956a1485bSTali Perry 	npcm_i2c_disable(bus);
235056a1485bSTali Perry 	spin_unlock_irqrestore(&bus->lock, lock_flags);
235156a1485bSTali Perry 	i2c_del_adapter(&bus->adap);
235256a1485bSTali Perry }
235356a1485bSTali Perry 
235456a1485bSTali Perry static const struct of_device_id npcm_i2c_bus_of_table[] = {
2355bbc38ed5STyrone Ting 	{ .compatible = "nuvoton,npcm750-i2c", .data = &npxm7xx_i2c_data },
2356bbc38ed5STyrone Ting 	{ .compatible = "nuvoton,npcm845-i2c", .data = &npxm8xx_i2c_data },
235756a1485bSTali Perry 	{}
235856a1485bSTali Perry };
235956a1485bSTali Perry MODULE_DEVICE_TABLE(of, npcm_i2c_bus_of_table);
236056a1485bSTali Perry 
236156a1485bSTali Perry static struct platform_driver npcm_i2c_bus_driver = {
236256a1485bSTali Perry 	.probe = npcm_i2c_probe_bus,
2363e190a0c3SUwe Kleine-König 	.remove_new = npcm_i2c_remove_bus,
236456a1485bSTali Perry 	.driver = {
236556a1485bSTali Perry 		.name = "nuvoton-i2c",
236656a1485bSTali Perry 		.of_match_table = npcm_i2c_bus_of_table,
236756a1485bSTali Perry 	}
236856a1485bSTali Perry };
236956a1485bSTali Perry 
2370e19e1abcSWolfram Sang module_platform_driver(npcm_i2c_bus_driver);
237156a1485bSTali Perry 
237256a1485bSTali Perry MODULE_AUTHOR("Avi Fishman <avi.fishman@gmail.com>");
237356a1485bSTali Perry MODULE_AUTHOR("Tali Perry <tali.perry@nuvoton.com>");
237456a1485bSTali Perry MODULE_AUTHOR("Tyrone Ting <kfting@nuvoton.com>");
237556a1485bSTali Perry MODULE_DESCRIPTION("Nuvoton I2C Bus Driver");
237656a1485bSTali Perry MODULE_LICENSE("GPL v2");
2377