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
2666ddc9132STyrone Ting struct smb_timing_t {
2676ddc9132STyrone Ting u32 core_clk;
2686ddc9132STyrone Ting u8 hldt;
2696ddc9132STyrone Ting u8 dbcnt;
2706ddc9132STyrone Ting u16 sclfrq;
2716ddc9132STyrone Ting u8 scllt;
2726ddc9132STyrone Ting u8 sclht;
2736ddc9132STyrone Ting bool fast_mode;
2746ddc9132STyrone Ting };
2756ddc9132STyrone Ting
2766ddc9132STyrone Ting static struct smb_timing_t smb_timing_100khz[] = {
2776ddc9132STyrone Ting {
2786ddc9132STyrone Ting .core_clk = 100000000, .hldt = 0x2A, .dbcnt = 0x4,
2796ddc9132STyrone Ting .sclfrq = 0xFB, .scllt = 0x0, .sclht = 0x0,
2806ddc9132STyrone Ting .fast_mode = false,
2816ddc9132STyrone Ting },
2826ddc9132STyrone Ting {
2836ddc9132STyrone Ting .core_clk = 62500000, .hldt = 0x2A, .dbcnt = 0x1,
2846ddc9132STyrone Ting .sclfrq = 0x9D, .scllt = 0x0, .sclht = 0x0,
2856ddc9132STyrone Ting .fast_mode = false,
2866ddc9132STyrone Ting },
2876ddc9132STyrone Ting {
2886ddc9132STyrone Ting .core_clk = 50000000, .hldt = 0x2A, .dbcnt = 0x1,
2896ddc9132STyrone Ting .sclfrq = 0x7E, .scllt = 0x0, .sclht = 0x0,
2906ddc9132STyrone Ting .fast_mode = false,
2916ddc9132STyrone Ting },
2926ddc9132STyrone Ting {
2936ddc9132STyrone Ting .core_clk = 48000000, .hldt = 0x2A, .dbcnt = 0x1,
2946ddc9132STyrone Ting .sclfrq = 0x79, .scllt = 0x0, .sclht = 0x0,
2956ddc9132STyrone Ting .fast_mode = false,
2966ddc9132STyrone Ting },
2976ddc9132STyrone Ting {
2986ddc9132STyrone Ting .core_clk = 40000000, .hldt = 0x2A, .dbcnt = 0x1,
2996ddc9132STyrone Ting .sclfrq = 0x65, .scllt = 0x0, .sclht = 0x0,
3006ddc9132STyrone Ting .fast_mode = false,
3016ddc9132STyrone Ting },
3026ddc9132STyrone Ting {
3036ddc9132STyrone Ting .core_clk = 30000000, .hldt = 0x2A, .dbcnt = 0x1,
3046ddc9132STyrone Ting .sclfrq = 0x4C, .scllt = 0x0, .sclht = 0x0,
3056ddc9132STyrone Ting .fast_mode = false,
3066ddc9132STyrone Ting },
3076ddc9132STyrone Ting {
3086ddc9132STyrone Ting .core_clk = 29000000, .hldt = 0x2A, .dbcnt = 0x1,
3096ddc9132STyrone Ting .sclfrq = 0x49, .scllt = 0x0, .sclht = 0x0,
3106ddc9132STyrone Ting .fast_mode = false,
3116ddc9132STyrone Ting },
3126ddc9132STyrone Ting {
3136ddc9132STyrone Ting .core_clk = 26000000, .hldt = 0x2A, .dbcnt = 0x1,
3146ddc9132STyrone Ting .sclfrq = 0x42, .scllt = 0x0, .sclht = 0x0,
3156ddc9132STyrone Ting .fast_mode = false,
3166ddc9132STyrone Ting },
3176ddc9132STyrone Ting {
3186ddc9132STyrone Ting .core_clk = 25000000, .hldt = 0x2A, .dbcnt = 0x1,
3196ddc9132STyrone Ting .sclfrq = 0x3F, .scllt = 0x0, .sclht = 0x0,
3206ddc9132STyrone Ting .fast_mode = false,
3216ddc9132STyrone Ting },
3226ddc9132STyrone Ting {
3236ddc9132STyrone Ting .core_clk = 24000000, .hldt = 0x2A, .dbcnt = 0x1,
3246ddc9132STyrone Ting .sclfrq = 0x3D, .scllt = 0x0, .sclht = 0x0,
3256ddc9132STyrone Ting .fast_mode = false,
3266ddc9132STyrone Ting },
3276ddc9132STyrone Ting {
3286ddc9132STyrone Ting .core_clk = 20000000, .hldt = 0x2A, .dbcnt = 0x1,
3296ddc9132STyrone Ting .sclfrq = 0x33, .scllt = 0x0, .sclht = 0x0,
3306ddc9132STyrone Ting .fast_mode = false,
3316ddc9132STyrone Ting },
3326ddc9132STyrone Ting {
3336ddc9132STyrone Ting .core_clk = 16180000, .hldt = 0x2A, .dbcnt = 0x1,
3346ddc9132STyrone Ting .sclfrq = 0x29, .scllt = 0x0, .sclht = 0x0,
3356ddc9132STyrone Ting .fast_mode = false,
3366ddc9132STyrone Ting },
3376ddc9132STyrone Ting {
3386ddc9132STyrone Ting .core_clk = 15000000, .hldt = 0x23, .dbcnt = 0x1,
3396ddc9132STyrone Ting .sclfrq = 0x26, .scllt = 0x0, .sclht = 0x0,
3406ddc9132STyrone Ting .fast_mode = false,
3416ddc9132STyrone Ting },
3426ddc9132STyrone Ting {
3436ddc9132STyrone Ting .core_clk = 13000000, .hldt = 0x1D, .dbcnt = 0x1,
3446ddc9132STyrone Ting .sclfrq = 0x21, .scllt = 0x0, .sclht = 0x0,
3456ddc9132STyrone Ting .fast_mode = false,
3466ddc9132STyrone Ting },
3476ddc9132STyrone Ting {
3486ddc9132STyrone Ting .core_clk = 12000000, .hldt = 0x1B, .dbcnt = 0x1,
3496ddc9132STyrone Ting .sclfrq = 0x1F, .scllt = 0x0, .sclht = 0x0,
3506ddc9132STyrone Ting .fast_mode = false,
3516ddc9132STyrone Ting },
3526ddc9132STyrone Ting {
3536ddc9132STyrone Ting .core_clk = 10000000, .hldt = 0x18, .dbcnt = 0x1,
3546ddc9132STyrone Ting .sclfrq = 0x1A, .scllt = 0x0, .sclht = 0x0,
3556ddc9132STyrone Ting .fast_mode = false,
3566ddc9132STyrone Ting },
3576ddc9132STyrone Ting {
3586ddc9132STyrone Ting .core_clk = 9000000, .hldt = 0x16, .dbcnt = 0x1,
3596ddc9132STyrone Ting .sclfrq = 0x17, .scllt = 0x0, .sclht = 0x0,
3606ddc9132STyrone Ting .fast_mode = false,
3616ddc9132STyrone Ting },
3626ddc9132STyrone Ting {
3636ddc9132STyrone Ting .core_clk = 8090000, .hldt = 0x14, .dbcnt = 0x1,
3646ddc9132STyrone Ting .sclfrq = 0x15, .scllt = 0x0, .sclht = 0x0,
3656ddc9132STyrone Ting .fast_mode = false,
3666ddc9132STyrone Ting },
3676ddc9132STyrone Ting {
3686ddc9132STyrone Ting .core_clk = 7500000, .hldt = 0x7, .dbcnt = 0x1,
3696ddc9132STyrone Ting .sclfrq = 0x13, .scllt = 0x0, .sclht = 0x0,
3706ddc9132STyrone Ting .fast_mode = false,
3716ddc9132STyrone Ting },
3726ddc9132STyrone Ting {
3736ddc9132STyrone Ting .core_clk = 6500000, .hldt = 0xE, .dbcnt = 0x1,
3746ddc9132STyrone Ting .sclfrq = 0x11, .scllt = 0x0, .sclht = 0x0,
3756ddc9132STyrone Ting .fast_mode = false,
3766ddc9132STyrone Ting },
3776ddc9132STyrone Ting {
3786ddc9132STyrone Ting .core_clk = 4000000, .hldt = 0x9, .dbcnt = 0x1,
3796ddc9132STyrone Ting .sclfrq = 0xB, .scllt = 0x0, .sclht = 0x0,
3806ddc9132STyrone Ting .fast_mode = false,
3816ddc9132STyrone Ting },
3826ddc9132STyrone Ting };
3836ddc9132STyrone Ting
3846ddc9132STyrone Ting static struct smb_timing_t smb_timing_400khz[] = {
3856ddc9132STyrone Ting {
3866ddc9132STyrone Ting .core_clk = 100000000, .hldt = 0x2A, .dbcnt = 0x3,
3876ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x47, .sclht = 0x35,
3886ddc9132STyrone Ting .fast_mode = true,
3896ddc9132STyrone Ting },
3906ddc9132STyrone Ting {
3916ddc9132STyrone Ting .core_clk = 62500000, .hldt = 0x2A, .dbcnt = 0x2,
3926ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x2C, .sclht = 0x22,
3936ddc9132STyrone Ting .fast_mode = true,
3946ddc9132STyrone Ting },
3956ddc9132STyrone Ting {
3966ddc9132STyrone Ting .core_clk = 50000000, .hldt = 0x21, .dbcnt = 0x1,
3976ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x24, .sclht = 0x1B,
3986ddc9132STyrone Ting .fast_mode = true,
3996ddc9132STyrone Ting },
4006ddc9132STyrone Ting {
4016ddc9132STyrone Ting .core_clk = 48000000, .hldt = 0x1E, .dbcnt = 0x1,
4026ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x24, .sclht = 0x19,
4036ddc9132STyrone Ting .fast_mode = true,
4046ddc9132STyrone Ting },
4056ddc9132STyrone Ting {
4066ddc9132STyrone Ting .core_clk = 40000000, .hldt = 0x1B, .dbcnt = 0x1,
4076ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x1E, .sclht = 0x14,
4086ddc9132STyrone Ting .fast_mode = true,
4096ddc9132STyrone Ting },
4106ddc9132STyrone Ting {
4116ddc9132STyrone Ting .core_clk = 33000000, .hldt = 0x15, .dbcnt = 0x1,
4126ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x19, .sclht = 0x11,
4136ddc9132STyrone Ting .fast_mode = true,
4146ddc9132STyrone Ting },
4156ddc9132STyrone Ting {
4166ddc9132STyrone Ting .core_clk = 30000000, .hldt = 0x15, .dbcnt = 0x1,
4176ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x19, .sclht = 0xD,
4186ddc9132STyrone Ting .fast_mode = true,
4196ddc9132STyrone Ting },
4206ddc9132STyrone Ting {
4216ddc9132STyrone Ting .core_clk = 29000000, .hldt = 0x11, .dbcnt = 0x1,
4226ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x15, .sclht = 0x10,
4236ddc9132STyrone Ting .fast_mode = true,
4246ddc9132STyrone Ting },
4256ddc9132STyrone Ting {
4266ddc9132STyrone Ting .core_clk = 26000000, .hldt = 0x10, .dbcnt = 0x1,
4276ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x13, .sclht = 0xE,
4286ddc9132STyrone Ting .fast_mode = true,
4296ddc9132STyrone Ting },
4306ddc9132STyrone Ting {
4316ddc9132STyrone Ting .core_clk = 25000000, .hldt = 0xF, .dbcnt = 0x1,
4326ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x13, .sclht = 0xD,
4336ddc9132STyrone Ting .fast_mode = true,
4346ddc9132STyrone Ting },
4356ddc9132STyrone Ting {
4366ddc9132STyrone Ting .core_clk = 24000000, .hldt = 0xD, .dbcnt = 0x1,
4376ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x12, .sclht = 0xD,
4386ddc9132STyrone Ting .fast_mode = true,
4396ddc9132STyrone Ting },
4406ddc9132STyrone Ting {
4416ddc9132STyrone Ting .core_clk = 20000000, .hldt = 0xB, .dbcnt = 0x1,
4426ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0xF, .sclht = 0xA,
4436ddc9132STyrone Ting .fast_mode = true,
4446ddc9132STyrone Ting },
4456ddc9132STyrone Ting {
4466ddc9132STyrone Ting .core_clk = 16180000, .hldt = 0xA, .dbcnt = 0x1,
4476ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0xC, .sclht = 0x9,
4486ddc9132STyrone Ting .fast_mode = true,
4496ddc9132STyrone Ting },
4506ddc9132STyrone Ting {
4516ddc9132STyrone Ting .core_clk = 15000000, .hldt = 0x9, .dbcnt = 0x1,
4526ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0xB, .sclht = 0x8,
4536ddc9132STyrone Ting .fast_mode = true,
4546ddc9132STyrone Ting },
4556ddc9132STyrone Ting {
4566ddc9132STyrone Ting .core_clk = 13000000, .hldt = 0x7, .dbcnt = 0x1,
4576ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0xA, .sclht = 0x7,
4586ddc9132STyrone Ting .fast_mode = true,
4596ddc9132STyrone Ting },
4606ddc9132STyrone Ting {
4616ddc9132STyrone Ting .core_clk = 12000000, .hldt = 0x7, .dbcnt = 0x1,
4626ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0xA, .sclht = 0x6,
4636ddc9132STyrone Ting .fast_mode = true,
4646ddc9132STyrone Ting },
4656ddc9132STyrone Ting {
4666ddc9132STyrone Ting .core_clk = 10000000, .hldt = 0x6, .dbcnt = 0x1,
4676ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x8, .sclht = 0x5,
4686ddc9132STyrone Ting .fast_mode = true,
4696ddc9132STyrone Ting },
4706ddc9132STyrone Ting };
4716ddc9132STyrone Ting
4726ddc9132STyrone Ting static struct smb_timing_t smb_timing_1000khz[] = {
4736ddc9132STyrone Ting {
4746ddc9132STyrone Ting .core_clk = 100000000, .hldt = 0x15, .dbcnt = 0x4,
4756ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x1C, .sclht = 0x15,
4766ddc9132STyrone Ting .fast_mode = true,
4776ddc9132STyrone Ting },
4786ddc9132STyrone Ting {
4796ddc9132STyrone Ting .core_clk = 62500000, .hldt = 0xF, .dbcnt = 0x3,
4806ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x11, .sclht = 0xE,
4816ddc9132STyrone Ting .fast_mode = true,
4826ddc9132STyrone Ting },
4836ddc9132STyrone Ting {
4846ddc9132STyrone Ting .core_clk = 50000000, .hldt = 0xA, .dbcnt = 0x2,
4856ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0xE, .sclht = 0xB,
4866ddc9132STyrone Ting .fast_mode = true,
4876ddc9132STyrone Ting },
4886ddc9132STyrone Ting {
4896ddc9132STyrone Ting .core_clk = 48000000, .hldt = 0x9, .dbcnt = 0x2,
4906ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0xD, .sclht = 0xB,
4916ddc9132STyrone Ting .fast_mode = true,
4926ddc9132STyrone Ting },
4936ddc9132STyrone Ting {
4946ddc9132STyrone Ting .core_clk = 41000000, .hldt = 0x9, .dbcnt = 0x2,
4956ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0xC, .sclht = 0x9,
4966ddc9132STyrone Ting .fast_mode = true,
4976ddc9132STyrone Ting },
4986ddc9132STyrone Ting {
4996ddc9132STyrone Ting .core_clk = 40000000, .hldt = 0x8, .dbcnt = 0x2,
5006ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0xB, .sclht = 0x9,
5016ddc9132STyrone Ting .fast_mode = true,
5026ddc9132STyrone Ting },
5036ddc9132STyrone Ting {
5046ddc9132STyrone Ting .core_clk = 33000000, .hldt = 0x7, .dbcnt = 0x1,
5056ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0xA, .sclht = 0x7,
5066ddc9132STyrone Ting .fast_mode = true,
5076ddc9132STyrone Ting },
5086ddc9132STyrone Ting {
5096ddc9132STyrone Ting .core_clk = 25000000, .hldt = 0x4, .dbcnt = 0x1,
5106ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x7, .sclht = 0x6,
5116ddc9132STyrone Ting .fast_mode = true,
5126ddc9132STyrone Ting },
5136ddc9132STyrone Ting {
5146ddc9132STyrone Ting .core_clk = 24000000, .hldt = 0x7, .dbcnt = 0x1,
5156ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x8, .sclht = 0x5,
5166ddc9132STyrone Ting .fast_mode = true,
5176ddc9132STyrone Ting },
5186ddc9132STyrone Ting {
5196ddc9132STyrone Ting .core_clk = 20000000, .hldt = 0x4, .dbcnt = 0x1,
5206ddc9132STyrone Ting .sclfrq = 0x0, .scllt = 0x6, .sclht = 0x4,
5216ddc9132STyrone Ting .fast_mode = true,
5226ddc9132STyrone Ting },
5236ddc9132STyrone Ting };
5246ddc9132STyrone Ting
525bbc38ed5STyrone Ting struct npcm_i2c_data {
526bbc38ed5STyrone Ting u8 fifo_size;
527bbc38ed5STyrone Ting u32 segctl_init_val;
528bbc38ed5STyrone Ting u8 txf_sts_tx_bytes;
529bbc38ed5STyrone Ting u8 rxf_sts_rx_bytes;
530bbc38ed5STyrone Ting u8 rxf_ctl_last_pec;
531bbc38ed5STyrone Ting };
532bbc38ed5STyrone Ting
533bbc38ed5STyrone Ting static const struct npcm_i2c_data npxm7xx_i2c_data = {
534bbc38ed5STyrone Ting .fifo_size = 16,
535bbc38ed5STyrone Ting .segctl_init_val = 0x0333F000,
536bbc38ed5STyrone Ting .txf_sts_tx_bytes = GENMASK(4, 0),
537bbc38ed5STyrone Ting .rxf_sts_rx_bytes = GENMASK(4, 0),
538bbc38ed5STyrone Ting .rxf_ctl_last_pec = BIT(5),
539bbc38ed5STyrone Ting };
540bbc38ed5STyrone Ting
541bbc38ed5STyrone Ting static const struct npcm_i2c_data npxm8xx_i2c_data = {
542bbc38ed5STyrone Ting .fifo_size = 32,
543bbc38ed5STyrone Ting .segctl_init_val = 0x9333F000,
544bbc38ed5STyrone Ting .txf_sts_tx_bytes = GENMASK(5, 0),
545bbc38ed5STyrone Ting .rxf_sts_rx_bytes = GENMASK(5, 0),
546bbc38ed5STyrone Ting .rxf_ctl_last_pec = BIT(7),
547bbc38ed5STyrone Ting };
548bbc38ed5STyrone Ting
54956a1485bSTali Perry /* Status of one I2C module */
55056a1485bSTali Perry struct npcm_i2c {
55156a1485bSTali Perry struct i2c_adapter adap;
55256a1485bSTali Perry struct device *dev;
55356a1485bSTali Perry unsigned char __iomem *reg;
554bbc38ed5STyrone Ting const struct npcm_i2c_data *data;
55556a1485bSTali Perry spinlock_t lock; /* IRQ synchronization */
55656a1485bSTali Perry struct completion cmd_complete;
55756a1485bSTali Perry int cmd_err;
55856a1485bSTali Perry struct i2c_msg *msgs;
55956a1485bSTali Perry int msgs_num;
56056a1485bSTali Perry int num;
56156a1485bSTali Perry u32 apb_clk;
56256a1485bSTali Perry struct i2c_bus_recovery_info rinfo;
56356a1485bSTali Perry enum i2c_state state;
56456a1485bSTali Perry enum i2c_oper operation;
56556a1485bSTali Perry enum i2c_mode master_or_slave;
56656a1485bSTali Perry enum i2c_state_ind stop_ind;
56756a1485bSTali Perry u8 dest_addr;
56856a1485bSTali Perry u8 *rd_buf;
56956a1485bSTali Perry u16 rd_size;
57056a1485bSTali Perry u16 rd_ind;
57156a1485bSTali Perry u8 *wr_buf;
57256a1485bSTali Perry u16 wr_size;
57356a1485bSTali Perry u16 wr_ind;
57456a1485bSTali Perry bool fifo_use;
57556a1485bSTali Perry u16 PEC_mask; /* PEC bit mask per slave address */
57656a1485bSTali Perry bool PEC_use;
57756a1485bSTali Perry bool read_block_use;
57856a1485bSTali Perry unsigned long int_time_stamp;
57956a1485bSTali Perry unsigned long bus_freq; /* in Hz */
580f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
581f5473692STali Perry u8 own_slave_addr;
582f5473692STali Perry struct i2c_client *slave;
583f5473692STali Perry int slv_rd_size;
584f5473692STali Perry int slv_rd_ind;
585f5473692STali Perry int slv_wr_size;
586f5473692STali Perry int slv_wr_ind;
587bbc38ed5STyrone Ting u8 slv_rd_buf[MAX_I2C_HW_FIFO_SIZE];
588bbc38ed5STyrone Ting u8 slv_wr_buf[MAX_I2C_HW_FIFO_SIZE];
589f5473692STali Perry #endif
59056a1485bSTali Perry u64 ber_cnt;
59156a1485bSTali Perry u64 rec_succ_cnt;
59256a1485bSTali Perry u64 rec_fail_cnt;
59356a1485bSTali Perry u64 nack_cnt;
59456a1485bSTali Perry u64 timeout_cnt;
5950bf58eb1STali Perry u64 tx_complete_cnt;
596b0118105STyrone Ting bool ber_state; /* Indicate the bus error state */
59756a1485bSTali Perry };
59856a1485bSTali Perry
npcm_i2c_select_bank(struct npcm_i2c * bus,enum i2c_bank bank)59956a1485bSTali Perry static inline void npcm_i2c_select_bank(struct npcm_i2c *bus,
60056a1485bSTali Perry enum i2c_bank bank)
60156a1485bSTali Perry {
60256a1485bSTali Perry u8 i2cctl3 = ioread8(bus->reg + NPCM_I2CCTL3);
60356a1485bSTali Perry
60456a1485bSTali Perry if (bank == I2C_BANK_0)
60556a1485bSTali Perry i2cctl3 = i2cctl3 & ~I2CCTL3_BNK_SEL;
60656a1485bSTali Perry else
60756a1485bSTali Perry i2cctl3 = i2cctl3 | I2CCTL3_BNK_SEL;
60856a1485bSTali Perry iowrite8(i2cctl3, bus->reg + NPCM_I2CCTL3);
60956a1485bSTali Perry }
61056a1485bSTali Perry
npcm_i2c_init_params(struct npcm_i2c * bus)61156a1485bSTali Perry static void npcm_i2c_init_params(struct npcm_i2c *bus)
61256a1485bSTali Perry {
61356a1485bSTali Perry bus->stop_ind = I2C_NO_STATUS_IND;
61456a1485bSTali Perry bus->rd_size = 0;
61556a1485bSTali Perry bus->wr_size = 0;
61656a1485bSTali Perry bus->rd_ind = 0;
61756a1485bSTali Perry bus->wr_ind = 0;
61856a1485bSTali Perry bus->read_block_use = false;
61956a1485bSTali Perry bus->int_time_stamp = 0;
62056a1485bSTali Perry bus->PEC_use = false;
62156a1485bSTali Perry bus->PEC_mask = 0;
622f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
623f5473692STali Perry if (bus->slave)
624f5473692STali Perry bus->master_or_slave = I2C_SLAVE;
625f5473692STali Perry #endif
62656a1485bSTali Perry }
62756a1485bSTali Perry
npcm_i2c_wr_byte(struct npcm_i2c * bus,u8 data)62856a1485bSTali Perry static inline void npcm_i2c_wr_byte(struct npcm_i2c *bus, u8 data)
62956a1485bSTali Perry {
63056a1485bSTali Perry iowrite8(data, bus->reg + NPCM_I2CSDA);
63156a1485bSTali Perry }
63256a1485bSTali Perry
npcm_i2c_rd_byte(struct npcm_i2c * bus)63356a1485bSTali Perry static inline u8 npcm_i2c_rd_byte(struct npcm_i2c *bus)
63456a1485bSTali Perry {
63556a1485bSTali Perry return ioread8(bus->reg + NPCM_I2CSDA);
63656a1485bSTali Perry }
63756a1485bSTali Perry
npcm_i2c_get_SCL(struct i2c_adapter * _adap)63856a1485bSTali Perry static int npcm_i2c_get_SCL(struct i2c_adapter *_adap)
63956a1485bSTali Perry {
64056a1485bSTali Perry struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
64156a1485bSTali Perry
642ea9f8426STyrone Ting return !!(I2CCTL3_SCL_LVL & ioread8(bus->reg + NPCM_I2CCTL3));
64356a1485bSTali Perry }
64456a1485bSTali Perry
npcm_i2c_get_SDA(struct i2c_adapter * _adap)64556a1485bSTali Perry static int npcm_i2c_get_SDA(struct i2c_adapter *_adap)
64656a1485bSTali Perry {
64756a1485bSTali Perry struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
64856a1485bSTali Perry
649ea9f8426STyrone Ting return !!(I2CCTL3_SDA_LVL & ioread8(bus->reg + NPCM_I2CCTL3));
65056a1485bSTali Perry }
65156a1485bSTali Perry
npcm_i2c_get_index(struct npcm_i2c * bus)65256a1485bSTali Perry static inline u16 npcm_i2c_get_index(struct npcm_i2c *bus)
65356a1485bSTali Perry {
65456a1485bSTali Perry if (bus->operation == I2C_READ_OPER)
65556a1485bSTali Perry return bus->rd_ind;
65656a1485bSTali Perry if (bus->operation == I2C_WRITE_OPER)
65756a1485bSTali Perry return bus->wr_ind;
65856a1485bSTali Perry return 0;
65956a1485bSTali Perry }
66056a1485bSTali Perry
66156a1485bSTali Perry /* quick protocol (just address) */
npcm_i2c_is_quick(struct npcm_i2c * bus)66256a1485bSTali Perry static inline bool npcm_i2c_is_quick(struct npcm_i2c *bus)
66356a1485bSTali Perry {
66456a1485bSTali Perry return bus->wr_size == 0 && bus->rd_size == 0;
66556a1485bSTali Perry }
66656a1485bSTali Perry
npcm_i2c_disable(struct npcm_i2c * bus)66756a1485bSTali Perry static void npcm_i2c_disable(struct npcm_i2c *bus)
66856a1485bSTali Perry {
66956a1485bSTali Perry u8 i2cctl2;
67056a1485bSTali Perry
671f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
672f5473692STali Perry int i;
673f5473692STali Perry
674f5473692STali Perry /* Slave addresses removal */
67547d506d1STali Perry for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR_SUPPORTED; i++)
676f5473692STali Perry iowrite8(0, bus->reg + npcm_i2caddr[i]);
677f5473692STali Perry
678f5473692STali Perry #endif
67956a1485bSTali Perry /* Disable module */
68056a1485bSTali Perry i2cctl2 = ioread8(bus->reg + NPCM_I2CCTL2);
68156a1485bSTali Perry i2cctl2 = i2cctl2 & ~I2CCTL2_ENABLE;
68256a1485bSTali Perry iowrite8(i2cctl2, bus->reg + NPCM_I2CCTL2);
68356a1485bSTali Perry
68456a1485bSTali Perry bus->state = I2C_DISABLE;
68556a1485bSTali Perry }
68656a1485bSTali Perry
npcm_i2c_enable(struct npcm_i2c * bus)68756a1485bSTali Perry static void npcm_i2c_enable(struct npcm_i2c *bus)
68856a1485bSTali Perry {
68956a1485bSTali Perry u8 i2cctl2 = ioread8(bus->reg + NPCM_I2CCTL2);
69056a1485bSTali Perry
69156a1485bSTali Perry i2cctl2 = i2cctl2 | I2CCTL2_ENABLE;
69256a1485bSTali Perry iowrite8(i2cctl2, bus->reg + NPCM_I2CCTL2);
69356a1485bSTali Perry bus->state = I2C_IDLE;
69456a1485bSTali Perry }
69556a1485bSTali Perry
69656a1485bSTali Perry /* enable\disable end of busy (EOB) interrupts */
npcm_i2c_eob_int(struct npcm_i2c * bus,bool enable)69756a1485bSTali Perry static inline void npcm_i2c_eob_int(struct npcm_i2c *bus, bool enable)
69856a1485bSTali Perry {
69956a1485bSTali Perry u8 val;
70056a1485bSTali Perry
70156a1485bSTali Perry /* Clear EO_BUSY pending bit: */
70256a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CCST3);
70356a1485bSTali Perry val = val | NPCM_I2CCST3_EO_BUSY;
70456a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CCST3);
70556a1485bSTali Perry
70656a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CCTL1);
70756a1485bSTali Perry val &= ~NPCM_I2CCTL1_RWS;
70856a1485bSTali Perry if (enable)
70956a1485bSTali Perry val |= NPCM_I2CCTL1_EOBINTE;
71056a1485bSTali Perry else
71156a1485bSTali Perry val &= ~NPCM_I2CCTL1_EOBINTE;
71256a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CCTL1);
71356a1485bSTali Perry }
71456a1485bSTali Perry
npcm_i2c_tx_fifo_empty(struct npcm_i2c * bus)71556a1485bSTali Perry static inline bool npcm_i2c_tx_fifo_empty(struct npcm_i2c *bus)
71656a1485bSTali Perry {
71756a1485bSTali Perry u8 tx_fifo_sts;
71856a1485bSTali Perry
71956a1485bSTali Perry tx_fifo_sts = ioread8(bus->reg + NPCM_I2CTXF_STS);
72056a1485bSTali Perry /* check if TX FIFO is not empty */
721bbc38ed5STyrone Ting if ((tx_fifo_sts & bus->data->txf_sts_tx_bytes) == 0)
72256a1485bSTali Perry return false;
72356a1485bSTali Perry
72456a1485bSTali Perry /* check if TX FIFO status bit is set: */
72556a1485bSTali Perry return !!FIELD_GET(NPCM_I2CTXF_STS_TX_THST, tx_fifo_sts);
72656a1485bSTali Perry }
72756a1485bSTali Perry
npcm_i2c_rx_fifo_full(struct npcm_i2c * bus)72856a1485bSTali Perry static inline bool npcm_i2c_rx_fifo_full(struct npcm_i2c *bus)
72956a1485bSTali Perry {
73056a1485bSTali Perry u8 rx_fifo_sts;
73156a1485bSTali Perry
73256a1485bSTali Perry rx_fifo_sts = ioread8(bus->reg + NPCM_I2CRXF_STS);
73356a1485bSTali Perry /* check if RX FIFO is not empty: */
734bbc38ed5STyrone Ting if ((rx_fifo_sts & bus->data->rxf_sts_rx_bytes) == 0)
73556a1485bSTali Perry return false;
73656a1485bSTali Perry
73756a1485bSTali Perry /* check if rx fifo full status is set: */
73856a1485bSTali Perry return !!FIELD_GET(NPCM_I2CRXF_STS_RX_THST, rx_fifo_sts);
73956a1485bSTali Perry }
74056a1485bSTali Perry
npcm_i2c_clear_fifo_int(struct npcm_i2c * bus)74156a1485bSTali Perry static inline void npcm_i2c_clear_fifo_int(struct npcm_i2c *bus)
74256a1485bSTali Perry {
74356a1485bSTali Perry u8 val;
74456a1485bSTali Perry
74556a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CFIF_CTS);
74656a1485bSTali Perry val = (val & NPCM_I2CFIF_CTS_SLVRSTR) | NPCM_I2CFIF_CTS_RXF_TXE;
74756a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CFIF_CTS);
74856a1485bSTali Perry }
74956a1485bSTali Perry
npcm_i2c_clear_tx_fifo(struct npcm_i2c * bus)75056a1485bSTali Perry static inline void npcm_i2c_clear_tx_fifo(struct npcm_i2c *bus)
75156a1485bSTali Perry {
75256a1485bSTali Perry u8 val;
75356a1485bSTali Perry
75456a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CTXF_STS);
75556a1485bSTali Perry val = val | NPCM_I2CTXF_STS_TX_THST;
75656a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CTXF_STS);
75756a1485bSTali Perry }
75856a1485bSTali Perry
npcm_i2c_clear_rx_fifo(struct npcm_i2c * bus)75956a1485bSTali Perry static inline void npcm_i2c_clear_rx_fifo(struct npcm_i2c *bus)
76056a1485bSTali Perry {
76156a1485bSTali Perry u8 val;
76256a1485bSTali Perry
76356a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CRXF_STS);
76456a1485bSTali Perry val = val | NPCM_I2CRXF_STS_RX_THST;
76556a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CRXF_STS);
76656a1485bSTali Perry }
76756a1485bSTali Perry
npcm_i2c_int_enable(struct npcm_i2c * bus,bool enable)76856a1485bSTali Perry static void npcm_i2c_int_enable(struct npcm_i2c *bus, bool enable)
76956a1485bSTali Perry {
77056a1485bSTali Perry u8 val;
77156a1485bSTali Perry
77256a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CCTL1);
77356a1485bSTali Perry val &= ~NPCM_I2CCTL1_RWS;
77456a1485bSTali Perry if (enable)
77556a1485bSTali Perry val |= NPCM_I2CCTL1_INTEN;
77656a1485bSTali Perry else
77756a1485bSTali Perry val &= ~NPCM_I2CCTL1_INTEN;
77856a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CCTL1);
77956a1485bSTali Perry }
78056a1485bSTali Perry
npcm_i2c_master_start(struct npcm_i2c * bus)78156a1485bSTali Perry static inline void npcm_i2c_master_start(struct npcm_i2c *bus)
78256a1485bSTali Perry {
78356a1485bSTali Perry u8 val;
78456a1485bSTali Perry
78556a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CCTL1);
78656a1485bSTali Perry val &= ~(NPCM_I2CCTL1_STOP | NPCM_I2CCTL1_ACK);
78756a1485bSTali Perry val |= NPCM_I2CCTL1_START;
78856a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CCTL1);
78956a1485bSTali Perry }
79056a1485bSTali Perry
npcm_i2c_master_stop(struct npcm_i2c * bus)79156a1485bSTali Perry static inline void npcm_i2c_master_stop(struct npcm_i2c *bus)
79256a1485bSTali Perry {
79356a1485bSTali Perry u8 val;
79456a1485bSTali Perry
79556a1485bSTali Perry /*
79656a1485bSTali Perry * override HW issue: I2C may fail to supply stop condition in Master
79756a1485bSTali Perry * Write operation.
79856a1485bSTali Perry * Need to delay at least 5 us from the last int, before issueing a stop
79956a1485bSTali Perry */
80056a1485bSTali Perry udelay(10); /* function called from interrupt, can't sleep */
80156a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CCTL1);
80256a1485bSTali Perry val &= ~(NPCM_I2CCTL1_START | NPCM_I2CCTL1_ACK);
80356a1485bSTali Perry val |= NPCM_I2CCTL1_STOP;
80456a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CCTL1);
80556a1485bSTali Perry
80656a1485bSTali Perry if (!bus->fifo_use)
80756a1485bSTali Perry return;
80856a1485bSTali Perry
80956a1485bSTali Perry npcm_i2c_select_bank(bus, I2C_BANK_1);
81056a1485bSTali Perry
81156a1485bSTali Perry if (bus->operation == I2C_READ_OPER)
81256a1485bSTali Perry npcm_i2c_clear_rx_fifo(bus);
81356a1485bSTali Perry else
81456a1485bSTali Perry npcm_i2c_clear_tx_fifo(bus);
81556a1485bSTali Perry npcm_i2c_clear_fifo_int(bus);
81656a1485bSTali Perry iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
81756a1485bSTali Perry }
81856a1485bSTali Perry
npcm_i2c_stall_after_start(struct npcm_i2c * bus,bool stall)81956a1485bSTali Perry static inline void npcm_i2c_stall_after_start(struct npcm_i2c *bus, bool stall)
82056a1485bSTali Perry {
82156a1485bSTali Perry u8 val;
82256a1485bSTali Perry
82356a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CCTL1);
82456a1485bSTali Perry val &= ~NPCM_I2CCTL1_RWS;
82556a1485bSTali Perry if (stall)
82656a1485bSTali Perry val |= NPCM_I2CCTL1_STASTRE;
82756a1485bSTali Perry else
82856a1485bSTali Perry val &= ~NPCM_I2CCTL1_STASTRE;
82956a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CCTL1);
83056a1485bSTali Perry }
83156a1485bSTali Perry
npcm_i2c_nack(struct npcm_i2c * bus)83256a1485bSTali Perry static inline void npcm_i2c_nack(struct npcm_i2c *bus)
83356a1485bSTali Perry {
83456a1485bSTali Perry u8 val;
83556a1485bSTali Perry
83656a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CCTL1);
83756a1485bSTali Perry val &= ~(NPCM_I2CCTL1_STOP | NPCM_I2CCTL1_START);
83856a1485bSTali Perry val |= NPCM_I2CCTL1_ACK;
83956a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CCTL1);
84056a1485bSTali Perry }
84156a1485bSTali Perry
npcm_i2c_clear_master_status(struct npcm_i2c * bus)842e5222d40STali Perry static inline void npcm_i2c_clear_master_status(struct npcm_i2c *bus)
843e5222d40STali Perry {
844e5222d40STali Perry u8 val;
845e5222d40STali Perry
846e5222d40STali Perry /* Clear NEGACK, STASTR and BER bits */
847e5222d40STali Perry val = NPCM_I2CST_BER | NPCM_I2CST_NEGACK | NPCM_I2CST_STASTR;
848e5222d40STali Perry iowrite8(val, bus->reg + NPCM_I2CST);
849e5222d40STali Perry }
850e5222d40STali Perry
851f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
npcm_i2c_slave_int_enable(struct npcm_i2c * bus,bool enable)852f5473692STali Perry static void npcm_i2c_slave_int_enable(struct npcm_i2c *bus, bool enable)
853f5473692STali Perry {
854f5473692STali Perry u8 i2cctl1;
855f5473692STali Perry
856f5473692STali Perry /* enable interrupt on slave match: */
857f5473692STali Perry i2cctl1 = ioread8(bus->reg + NPCM_I2CCTL1);
858f5473692STali Perry i2cctl1 &= ~NPCM_I2CCTL1_RWS;
859f5473692STali Perry if (enable)
860f5473692STali Perry i2cctl1 |= NPCM_I2CCTL1_NMINTE;
861f5473692STali Perry else
862f5473692STali Perry i2cctl1 &= ~NPCM_I2CCTL1_NMINTE;
863f5473692STali Perry iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1);
864f5473692STali Perry }
865f5473692STali Perry
npcm_i2c_slave_enable(struct npcm_i2c * bus,enum i2c_addr addr_type,u8 addr,bool enable)866f5473692STali Perry static int npcm_i2c_slave_enable(struct npcm_i2c *bus, enum i2c_addr addr_type,
867f5473692STali Perry u8 addr, bool enable)
868f5473692STali Perry {
869f5473692STali Perry u8 i2cctl1;
870f5473692STali Perry u8 i2cctl3;
871f5473692STali Perry u8 sa_reg;
872f5473692STali Perry
873f5473692STali Perry sa_reg = (addr & 0x7F) | FIELD_PREP(NPCM_I2CADDR_SAEN, enable);
874f5473692STali Perry if (addr_type == I2C_GC_ADDR) {
875f5473692STali Perry i2cctl1 = ioread8(bus->reg + NPCM_I2CCTL1);
876f5473692STali Perry if (enable)
877f5473692STali Perry i2cctl1 |= NPCM_I2CCTL1_GCMEN;
878f5473692STali Perry else
879f5473692STali Perry i2cctl1 &= ~NPCM_I2CCTL1_GCMEN;
880f5473692STali Perry iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1);
881f5473692STali Perry return 0;
88247d506d1STali Perry } else if (addr_type == I2C_ARP_ADDR) {
883f5473692STali Perry i2cctl3 = ioread8(bus->reg + NPCM_I2CCTL3);
884f5473692STali Perry if (enable)
885f5473692STali Perry i2cctl3 |= I2CCTL3_ARPMEN;
886f5473692STali Perry else
887f5473692STali Perry i2cctl3 &= ~I2CCTL3_ARPMEN;
888f5473692STali Perry iowrite8(i2cctl3, bus->reg + NPCM_I2CCTL3);
889f5473692STali Perry return 0;
890f5473692STali Perry }
89147d506d1STali Perry if (addr_type > I2C_SLAVE_ADDR2 && addr_type <= I2C_SLAVE_ADDR10)
89247d506d1STali Perry dev_err(bus->dev, "try to enable more than 2 SA not supported\n");
89347d506d1STali Perry
894f5473692STali Perry if (addr_type >= I2C_ARP_ADDR)
895f5473692STali Perry return -EFAULT;
89647d506d1STali Perry
897f5473692STali Perry /* Set and enable the address */
898f5473692STali Perry iowrite8(sa_reg, bus->reg + npcm_i2caddr[addr_type]);
899f5473692STali Perry npcm_i2c_slave_int_enable(bus, enable);
90047d506d1STali Perry
901f5473692STali Perry return 0;
902f5473692STali Perry }
903f5473692STali Perry #endif
904f5473692STali Perry
npcm_i2c_reset(struct npcm_i2c * bus)90556a1485bSTali Perry static void npcm_i2c_reset(struct npcm_i2c *bus)
90656a1485bSTali Perry {
90756a1485bSTali Perry /*
90856a1485bSTali Perry * Save I2CCTL1 relevant bits. It is being cleared when the module
90956a1485bSTali Perry * is disabled.
91056a1485bSTali Perry */
91156a1485bSTali Perry u8 i2cctl1;
912f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
913f5473692STali Perry u8 addr;
914f5473692STali Perry #endif
91556a1485bSTali Perry
91656a1485bSTali Perry i2cctl1 = ioread8(bus->reg + NPCM_I2CCTL1);
91756a1485bSTali Perry
91856a1485bSTali Perry npcm_i2c_disable(bus);
91956a1485bSTali Perry npcm_i2c_enable(bus);
92056a1485bSTali Perry
92156a1485bSTali Perry /* Restore NPCM_I2CCTL1 Status */
92256a1485bSTali Perry i2cctl1 &= ~NPCM_I2CCTL1_RWS;
92356a1485bSTali Perry iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1);
92456a1485bSTali Perry
92556a1485bSTali Perry /* Clear BB (BUS BUSY) bit */
92656a1485bSTali Perry iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
92756a1485bSTali Perry iowrite8(0xFF, bus->reg + NPCM_I2CST);
92856a1485bSTali Perry
929e5222d40STali Perry /* Clear and disable EOB */
930e5222d40STali Perry npcm_i2c_eob_int(bus, false);
93156a1485bSTali Perry
93256a1485bSTali Perry /* Clear all fifo bits: */
93356a1485bSTali Perry iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS);
93456a1485bSTali Perry
935f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
936f5473692STali Perry if (bus->slave) {
937f5473692STali Perry addr = bus->slave->addr;
938f5473692STali Perry npcm_i2c_slave_enable(bus, I2C_SLAVE_ADDR1, addr, true);
939f5473692STali Perry }
940f5473692STali Perry #endif
941f5473692STali Perry
942ffad0a35STyrone Ting /* Clear status bits for spurious interrupts */
943e5222d40STali Perry npcm_i2c_clear_master_status(bus);
944e5222d40STali Perry
94556a1485bSTali Perry bus->state = I2C_IDLE;
94656a1485bSTali Perry }
94756a1485bSTali Perry
npcm_i2c_is_master(struct npcm_i2c * bus)94856a1485bSTali Perry static inline bool npcm_i2c_is_master(struct npcm_i2c *bus)
94956a1485bSTali Perry {
95056a1485bSTali Perry return !!FIELD_GET(NPCM_I2CST_MASTER, ioread8(bus->reg + NPCM_I2CST));
95156a1485bSTali Perry }
95256a1485bSTali Perry
npcm_i2c_callback(struct npcm_i2c * bus,enum i2c_state_ind op_status,u16 info)95356a1485bSTali Perry static void npcm_i2c_callback(struct npcm_i2c *bus,
95456a1485bSTali Perry enum i2c_state_ind op_status, u16 info)
95556a1485bSTali Perry {
95656a1485bSTali Perry struct i2c_msg *msgs;
95756a1485bSTali Perry int msgs_num;
95892e73d80SWilliam A. Kennington III bool do_complete = false;
95956a1485bSTali Perry
96056a1485bSTali Perry msgs = bus->msgs;
96156a1485bSTali Perry msgs_num = bus->msgs_num;
96256a1485bSTali Perry /*
96356a1485bSTali Perry * check that transaction was not timed-out, and msgs still
96456a1485bSTali Perry * holds a valid value.
96556a1485bSTali Perry */
96656a1485bSTali Perry if (!msgs)
96756a1485bSTali Perry return;
96856a1485bSTali Perry
96956a1485bSTali Perry if (completion_done(&bus->cmd_complete))
97056a1485bSTali Perry return;
97156a1485bSTali Perry
97256a1485bSTali Perry switch (op_status) {
97356a1485bSTali Perry case I2C_MASTER_DONE_IND:
97456a1485bSTali Perry bus->cmd_err = bus->msgs_num;
9750bf58eb1STali Perry if (bus->tx_complete_cnt < ULLONG_MAX)
9760bf58eb1STali Perry bus->tx_complete_cnt++;
97756a1485bSTali Perry fallthrough;
97856a1485bSTali Perry case I2C_BLOCK_BYTES_ERR_IND:
97956a1485bSTali Perry /* Master tx finished and all transmit bytes were sent */
98056a1485bSTali Perry if (bus->msgs) {
98156a1485bSTali Perry if (msgs[0].flags & I2C_M_RD)
98256a1485bSTali Perry msgs[0].len = info;
98356a1485bSTali Perry else if (msgs_num == 2 &&
98456a1485bSTali Perry msgs[1].flags & I2C_M_RD)
98556a1485bSTali Perry msgs[1].len = info;
98656a1485bSTali Perry }
98792e73d80SWilliam A. Kennington III do_complete = true;
98856a1485bSTali Perry break;
98956a1485bSTali Perry case I2C_NACK_IND:
99056a1485bSTali Perry /* MASTER transmit got a NACK before tx all bytes */
99156a1485bSTali Perry bus->cmd_err = -ENXIO;
99292e73d80SWilliam A. Kennington III do_complete = true;
99356a1485bSTali Perry break;
99456a1485bSTali Perry case I2C_BUS_ERR_IND:
99556a1485bSTali Perry /* Bus error */
99656a1485bSTali Perry bus->cmd_err = -EAGAIN;
99792e73d80SWilliam A. Kennington III do_complete = true;
99856a1485bSTali Perry break;
99956a1485bSTali Perry case I2C_WAKE_UP_IND:
100056a1485bSTali Perry /* I2C wake up */
100156a1485bSTali Perry break;
100256a1485bSTali Perry default:
100356a1485bSTali Perry break;
100456a1485bSTali Perry }
100556a1485bSTali Perry
100656a1485bSTali Perry bus->operation = I2C_NO_OPER;
1007f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
1008f5473692STali Perry if (bus->slave)
1009f5473692STali Perry bus->master_or_slave = I2C_SLAVE;
1010f5473692STali Perry #endif
101192e73d80SWilliam A. Kennington III if (do_complete)
101292e73d80SWilliam A. Kennington III complete(&bus->cmd_complete);
101356a1485bSTali Perry }
101456a1485bSTali Perry
npcm_i2c_fifo_usage(struct npcm_i2c * bus)101556a1485bSTali Perry static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus)
101656a1485bSTali Perry {
101756a1485bSTali Perry if (bus->operation == I2C_WRITE_OPER)
1018bbc38ed5STyrone Ting return (bus->data->txf_sts_tx_bytes &
101956a1485bSTali Perry ioread8(bus->reg + NPCM_I2CTXF_STS));
102056a1485bSTali Perry if (bus->operation == I2C_READ_OPER)
1021bbc38ed5STyrone Ting return (bus->data->rxf_sts_rx_bytes &
102256a1485bSTali Perry ioread8(bus->reg + NPCM_I2CRXF_STS));
102356a1485bSTali Perry return 0;
102456a1485bSTali Perry }
102556a1485bSTali Perry
npcm_i2c_write_to_fifo_master(struct npcm_i2c * bus,u16 max_bytes)102656a1485bSTali Perry static void npcm_i2c_write_to_fifo_master(struct npcm_i2c *bus, u16 max_bytes)
102756a1485bSTali Perry {
102856a1485bSTali Perry u8 size_free_fifo;
102956a1485bSTali Perry
103056a1485bSTali Perry /*
103156a1485bSTali Perry * Fill the FIFO, while the FIFO is not full and there are more bytes
103256a1485bSTali Perry * to write
103356a1485bSTali Perry */
1034bbc38ed5STyrone Ting size_free_fifo = bus->data->fifo_size - npcm_i2c_fifo_usage(bus);
103556a1485bSTali Perry while (max_bytes-- && size_free_fifo) {
103656a1485bSTali Perry if (bus->wr_ind < bus->wr_size)
103756a1485bSTali Perry npcm_i2c_wr_byte(bus, bus->wr_buf[bus->wr_ind++]);
103856a1485bSTali Perry else
103956a1485bSTali Perry npcm_i2c_wr_byte(bus, 0xFF);
1040bbc38ed5STyrone Ting size_free_fifo = bus->data->fifo_size - npcm_i2c_fifo_usage(bus);
104156a1485bSTali Perry }
104256a1485bSTali Perry }
104356a1485bSTali Perry
104456a1485bSTali Perry /*
104556a1485bSTali Perry * npcm_i2c_set_fifo:
104656a1485bSTali Perry * configure the FIFO before using it. If nread is -1 RX FIFO will not be
104756a1485bSTali Perry * configured. same for nwrite
104856a1485bSTali Perry */
npcm_i2c_set_fifo(struct npcm_i2c * bus,int nread,int nwrite)104956a1485bSTali Perry static void npcm_i2c_set_fifo(struct npcm_i2c *bus, int nread, int nwrite)
105056a1485bSTali Perry {
105156a1485bSTali Perry u8 rxf_ctl = 0;
105256a1485bSTali Perry
105356a1485bSTali Perry if (!bus->fifo_use)
105456a1485bSTali Perry return;
105556a1485bSTali Perry npcm_i2c_select_bank(bus, I2C_BANK_1);
105656a1485bSTali Perry npcm_i2c_clear_tx_fifo(bus);
105756a1485bSTali Perry npcm_i2c_clear_rx_fifo(bus);
105856a1485bSTali Perry
105956a1485bSTali Perry /* configure RX FIFO */
106056a1485bSTali Perry if (nread > 0) {
1061bbc38ed5STyrone Ting rxf_ctl = min_t(int, nread, bus->data->fifo_size);
106256a1485bSTali Perry
106356a1485bSTali Perry /* set LAST bit. if LAST is set next FIFO packet is nacked */
1064bbc38ed5STyrone Ting if (nread <= bus->data->fifo_size)
1065bbc38ed5STyrone Ting rxf_ctl |= bus->data->rxf_ctl_last_pec;
106656a1485bSTali Perry
106756a1485bSTali Perry /*
106856a1485bSTali Perry * if we are about to read the first byte in blk rd mode,
106956a1485bSTali Perry * don't NACK it. If slave returns zero size HW can't NACK
10700c47dd7dSJonathan Neuschäfer * it immediately, it will read extra byte and then NACK.
107156a1485bSTali Perry */
107256a1485bSTali Perry if (bus->rd_ind == 0 && bus->read_block_use) {
107356a1485bSTali Perry /* set fifo to read one byte, no last: */
107456a1485bSTali Perry rxf_ctl = 1;
107556a1485bSTali Perry }
107656a1485bSTali Perry
107756a1485bSTali Perry /* set fifo size: */
107856a1485bSTali Perry iowrite8(rxf_ctl, bus->reg + NPCM_I2CRXF_CTL);
107956a1485bSTali Perry }
108056a1485bSTali Perry
108156a1485bSTali Perry /* configure TX FIFO */
108256a1485bSTali Perry if (nwrite > 0) {
1083bbc38ed5STyrone Ting if (nwrite > bus->data->fifo_size)
108456a1485bSTali Perry /* data to send is more then FIFO size. */
1085bbc38ed5STyrone Ting iowrite8(bus->data->fifo_size, bus->reg + NPCM_I2CTXF_CTL);
108656a1485bSTali Perry else
108756a1485bSTali Perry iowrite8(nwrite, bus->reg + NPCM_I2CTXF_CTL);
108856a1485bSTali Perry
108956a1485bSTali Perry npcm_i2c_clear_tx_fifo(bus);
109056a1485bSTali Perry }
109156a1485bSTali Perry }
109256a1485bSTali Perry
npcm_i2c_read_fifo(struct npcm_i2c * bus,u8 bytes_in_fifo)109356a1485bSTali Perry static void npcm_i2c_read_fifo(struct npcm_i2c *bus, u8 bytes_in_fifo)
109456a1485bSTali Perry {
109556a1485bSTali Perry u8 data;
109656a1485bSTali Perry
109756a1485bSTali Perry while (bytes_in_fifo--) {
109856a1485bSTali Perry data = npcm_i2c_rd_byte(bus);
109956a1485bSTali Perry if (bus->rd_ind < bus->rd_size)
110056a1485bSTali Perry bus->rd_buf[bus->rd_ind++] = data;
110156a1485bSTali Perry }
110256a1485bSTali Perry }
110356a1485bSTali Perry
npcm_i2c_master_abort(struct npcm_i2c * bus)110456a1485bSTali Perry static void npcm_i2c_master_abort(struct npcm_i2c *bus)
110556a1485bSTali Perry {
110656a1485bSTali Perry /* Only current master is allowed to issue a stop condition */
110756a1485bSTali Perry if (!npcm_i2c_is_master(bus))
110856a1485bSTali Perry return;
110956a1485bSTali Perry
111056a1485bSTali Perry npcm_i2c_eob_int(bus, true);
111156a1485bSTali Perry npcm_i2c_master_stop(bus);
111256a1485bSTali Perry npcm_i2c_clear_master_status(bus);
111356a1485bSTali Perry }
111456a1485bSTali Perry
1115f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
npcm_i2c_get_slave_addr(struct npcm_i2c * bus,enum i2c_addr addr_type)1116f5473692STali Perry static u8 npcm_i2c_get_slave_addr(struct npcm_i2c *bus, enum i2c_addr addr_type)
1117f5473692STali Perry {
111847d506d1STali Perry if (addr_type > I2C_SLAVE_ADDR2 && addr_type <= I2C_SLAVE_ADDR10)
111947d506d1STali Perry dev_err(bus->dev, "get slave: try to use more than 2 SA not supported\n");
1120f5473692STali Perry
11215a1934f1SZhang Songyi return ioread8(bus->reg + npcm_i2caddr[addr_type]);
1122f5473692STali Perry }
1123f5473692STali Perry
npcm_i2c_remove_slave_addr(struct npcm_i2c * bus,u8 slave_add)1124f5473692STali Perry static int npcm_i2c_remove_slave_addr(struct npcm_i2c *bus, u8 slave_add)
1125f5473692STali Perry {
1126f5473692STali Perry int i;
1127f5473692STali Perry
1128f5473692STali Perry /* Set the enable bit */
1129f5473692STali Perry slave_add |= 0x80;
113047d506d1STali Perry
113147d506d1STali Perry for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR_SUPPORTED; i++) {
1132f5473692STali Perry if (ioread8(bus->reg + npcm_i2caddr[i]) == slave_add)
1133f5473692STali Perry iowrite8(0, bus->reg + npcm_i2caddr[i]);
1134f5473692STali Perry }
113547d506d1STali Perry
1136f5473692STali Perry return 0;
1137f5473692STali Perry }
1138f5473692STali Perry
npcm_i2c_write_fifo_slave(struct npcm_i2c * bus,u16 max_bytes)1139f5473692STali Perry static void npcm_i2c_write_fifo_slave(struct npcm_i2c *bus, u16 max_bytes)
1140f5473692STali Perry {
1141f5473692STali Perry /*
1142f5473692STali Perry * Fill the FIFO, while the FIFO is not full and there are more bytes
1143f5473692STali Perry * to write
1144f5473692STali Perry */
1145f5473692STali Perry npcm_i2c_clear_fifo_int(bus);
1146f5473692STali Perry npcm_i2c_clear_tx_fifo(bus);
1147f5473692STali Perry iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
1148bbc38ed5STyrone Ting while (max_bytes-- && bus->data->fifo_size != npcm_i2c_fifo_usage(bus)) {
1149f5473692STali Perry if (bus->slv_wr_size <= 0)
1150f5473692STali Perry break;
1151bbc38ed5STyrone Ting bus->slv_wr_ind = bus->slv_wr_ind & (bus->data->fifo_size - 1);
1152f5473692STali Perry npcm_i2c_wr_byte(bus, bus->slv_wr_buf[bus->slv_wr_ind]);
1153f5473692STali Perry bus->slv_wr_ind++;
1154bbc38ed5STyrone Ting bus->slv_wr_ind = bus->slv_wr_ind & (bus->data->fifo_size - 1);
1155f5473692STali Perry bus->slv_wr_size--;
1156f5473692STali Perry }
1157f5473692STali Perry }
1158f5473692STali Perry
npcm_i2c_read_fifo_slave(struct npcm_i2c * bus,u8 bytes_in_fifo)1159f5473692STali Perry static void npcm_i2c_read_fifo_slave(struct npcm_i2c *bus, u8 bytes_in_fifo)
1160f5473692STali Perry {
1161f5473692STali Perry u8 data;
1162f5473692STali Perry
1163f5473692STali Perry if (!bus->slave)
1164f5473692STali Perry return;
1165f5473692STali Perry
1166f5473692STali Perry while (bytes_in_fifo--) {
1167f5473692STali Perry data = npcm_i2c_rd_byte(bus);
1168f5473692STali Perry
1169bbc38ed5STyrone Ting bus->slv_rd_ind = bus->slv_rd_ind & (bus->data->fifo_size - 1);
1170f5473692STali Perry bus->slv_rd_buf[bus->slv_rd_ind] = data;
1171f5473692STali Perry bus->slv_rd_ind++;
1172f5473692STali Perry
1173f5473692STali Perry /* 1st byte is length in block protocol: */
1174f5473692STali Perry if (bus->slv_rd_ind == 1 && bus->read_block_use)
1175f5473692STali Perry bus->slv_rd_size = data + bus->PEC_use + 1;
1176f5473692STali Perry }
1177f5473692STali Perry }
1178f5473692STali Perry
npcm_i2c_slave_get_wr_buf(struct npcm_i2c * bus)1179f5473692STali Perry static int npcm_i2c_slave_get_wr_buf(struct npcm_i2c *bus)
1180f5473692STali Perry {
1181f5473692STali Perry int i;
1182f5473692STali Perry u8 value;
1183f5473692STali Perry int ind;
1184f5473692STali Perry int ret = bus->slv_wr_ind;
1185f5473692STali Perry
1186f5473692STali Perry /* fill a cyclic buffer */
1187bbc38ed5STyrone Ting for (i = 0; i < bus->data->fifo_size; i++) {
1188bbc38ed5STyrone Ting if (bus->slv_wr_size >= bus->data->fifo_size)
1189f5473692STali Perry break;
1190d7aa1b14STali Perry if (bus->state == I2C_SLAVE_MATCH) {
1191f5473692STali Perry i2c_slave_event(bus->slave, I2C_SLAVE_READ_REQUESTED, &value);
1192d7aa1b14STali Perry bus->state = I2C_OPER_STARTED;
1193d7aa1b14STali Perry } else {
1194f5473692STali Perry i2c_slave_event(bus->slave, I2C_SLAVE_READ_PROCESSED, &value);
1195f5473692STali Perry }
1196bbc38ed5STyrone Ting ind = (bus->slv_wr_ind + bus->slv_wr_size) & (bus->data->fifo_size - 1);
1197f5473692STali Perry bus->slv_wr_buf[ind] = value;
1198f5473692STali Perry bus->slv_wr_size++;
1199f5473692STali Perry }
1200bbc38ed5STyrone Ting return bus->data->fifo_size - ret;
1201f5473692STali Perry }
1202f5473692STali Perry
npcm_i2c_slave_send_rd_buf(struct npcm_i2c * bus)1203f5473692STali Perry static void npcm_i2c_slave_send_rd_buf(struct npcm_i2c *bus)
1204f5473692STali Perry {
1205f5473692STali Perry int i;
1206f5473692STali Perry
1207f5473692STali Perry for (i = 0; i < bus->slv_rd_ind; i++)
1208f5473692STali Perry i2c_slave_event(bus->slave, I2C_SLAVE_WRITE_RECEIVED,
1209f5473692STali Perry &bus->slv_rd_buf[i]);
1210f5473692STali Perry /*
1211f5473692STali Perry * once we send bytes up, need to reset the counter of the wr buf
1212f5473692STali Perry * got data from master (new offset in device), ignore wr fifo:
1213f5473692STali Perry */
1214f5473692STali Perry if (bus->slv_rd_ind) {
1215f5473692STali Perry bus->slv_wr_size = 0;
1216f5473692STali Perry bus->slv_wr_ind = 0;
1217f5473692STali Perry }
1218f5473692STali Perry
1219f5473692STali Perry bus->slv_rd_ind = 0;
1220f5473692STali Perry bus->slv_rd_size = bus->adap.quirks->max_read_len;
1221f5473692STali Perry
1222f5473692STali Perry npcm_i2c_clear_fifo_int(bus);
1223f5473692STali Perry npcm_i2c_clear_rx_fifo(bus);
1224f5473692STali Perry }
1225f5473692STali Perry
npcm_i2c_slave_receive(struct npcm_i2c * bus,u16 nread,u8 * read_data)1226f5473692STali Perry static void npcm_i2c_slave_receive(struct npcm_i2c *bus, u16 nread,
1227f5473692STali Perry u8 *read_data)
1228f5473692STali Perry {
1229f5473692STali Perry bus->state = I2C_OPER_STARTED;
1230f5473692STali Perry bus->operation = I2C_READ_OPER;
1231f5473692STali Perry bus->slv_rd_size = nread;
1232f5473692STali Perry bus->slv_rd_ind = 0;
1233f5473692STali Perry
1234f5473692STali Perry iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
1235bbc38ed5STyrone Ting iowrite8(bus->data->fifo_size, bus->reg + NPCM_I2CRXF_CTL);
1236f5473692STali Perry npcm_i2c_clear_tx_fifo(bus);
1237f5473692STali Perry npcm_i2c_clear_rx_fifo(bus);
1238f5473692STali Perry }
1239f5473692STali Perry
npcm_i2c_slave_xmit(struct npcm_i2c * bus,u16 nwrite,u8 * write_data)1240f5473692STali Perry static void npcm_i2c_slave_xmit(struct npcm_i2c *bus, u16 nwrite,
1241f5473692STali Perry u8 *write_data)
1242f5473692STali Perry {
1243f5473692STali Perry if (nwrite == 0)
1244f5473692STali Perry return;
1245f5473692STali Perry
1246f5473692STali Perry bus->operation = I2C_WRITE_OPER;
1247f5473692STali Perry
1248f5473692STali Perry /* get the next buffer */
1249f5473692STali Perry npcm_i2c_slave_get_wr_buf(bus);
1250f5473692STali Perry npcm_i2c_write_fifo_slave(bus, nwrite);
1251f5473692STali Perry }
1252f5473692STali Perry
1253f5473692STali Perry /*
1254f5473692STali Perry * npcm_i2c_slave_wr_buf_sync:
1255f5473692STali Perry * currently slave IF only supports single byte operations.
12560c47dd7dSJonathan Neuschäfer * in order to utilize the npcm HW FIFO, the driver will ask for 16 bytes
1257f5473692STali Perry * at a time, pack them in buffer, and then transmit them all together
1258f5473692STali Perry * to the FIFO and onward to the bus.
1259f5473692STali Perry * NACK on read will be once reached to bus->adap->quirks->max_read_len.
1260f5473692STali Perry * sending a NACK wherever the backend requests for it is not supported.
1261f5473692STali Perry * the next two functions allow reading to local buffer before writing it all
1262f5473692STali Perry * to the HW FIFO.
1263f5473692STali Perry */
npcm_i2c_slave_wr_buf_sync(struct npcm_i2c * bus)1264f5473692STali Perry static void npcm_i2c_slave_wr_buf_sync(struct npcm_i2c *bus)
1265f5473692STali Perry {
1266f5473692STali Perry int left_in_fifo;
1267f5473692STali Perry
1268bbc38ed5STyrone Ting left_in_fifo = bus->data->txf_sts_tx_bytes &
1269bbc38ed5STyrone Ting ioread8(bus->reg + NPCM_I2CTXF_STS);
1270f5473692STali Perry
1271f5473692STali Perry /* fifo already full: */
1272bbc38ed5STyrone Ting if (left_in_fifo >= bus->data->fifo_size ||
1273bbc38ed5STyrone Ting bus->slv_wr_size >= bus->data->fifo_size)
1274f5473692STali Perry return;
1275f5473692STali Perry
1276f5473692STali Perry /* update the wr fifo index back to the untransmitted bytes: */
1277f5473692STali Perry bus->slv_wr_ind = bus->slv_wr_ind - left_in_fifo;
1278f5473692STali Perry bus->slv_wr_size = bus->slv_wr_size + left_in_fifo;
1279f5473692STali Perry
1280f5473692STali Perry if (bus->slv_wr_ind < 0)
1281bbc38ed5STyrone Ting bus->slv_wr_ind += bus->data->fifo_size;
1282f5473692STali Perry }
1283f5473692STali Perry
npcm_i2c_slave_rd_wr(struct npcm_i2c * bus)1284f5473692STali Perry static void npcm_i2c_slave_rd_wr(struct npcm_i2c *bus)
1285f5473692STali Perry {
1286f5473692STali Perry if (NPCM_I2CST_XMIT & ioread8(bus->reg + NPCM_I2CST)) {
1287f5473692STali Perry /*
1288f5473692STali Perry * Slave got an address match with direction bit 1 so it should
1289f5473692STali Perry * transmit data. Write till the master will NACK
1290f5473692STali Perry */
1291f5473692STali Perry bus->operation = I2C_WRITE_OPER;
1292f5473692STali Perry npcm_i2c_slave_xmit(bus, bus->adap.quirks->max_write_len,
1293f5473692STali Perry bus->slv_wr_buf);
1294f5473692STali Perry } else {
1295f5473692STali Perry /*
1296f5473692STali Perry * Slave got an address match with direction bit 0 so it should
1297f5473692STali Perry * receive data.
1298f5473692STali Perry * this module does not support saying no to bytes.
1299f5473692STali Perry * it will always ACK.
1300f5473692STali Perry */
1301f5473692STali Perry bus->operation = I2C_READ_OPER;
1302f5473692STali Perry npcm_i2c_read_fifo_slave(bus, npcm_i2c_fifo_usage(bus));
1303f5473692STali Perry bus->stop_ind = I2C_SLAVE_RCV_IND;
1304f5473692STali Perry npcm_i2c_slave_send_rd_buf(bus);
1305f5473692STali Perry npcm_i2c_slave_receive(bus, bus->adap.quirks->max_read_len,
1306f5473692STali Perry bus->slv_rd_buf);
1307f5473692STali Perry }
1308f5473692STali Perry }
1309f5473692STali Perry
npcm_i2c_int_slave_handler(struct npcm_i2c * bus)1310f5473692STali Perry static irqreturn_t npcm_i2c_int_slave_handler(struct npcm_i2c *bus)
1311f5473692STali Perry {
1312f5473692STali Perry u8 val;
1313f5473692STali Perry irqreturn_t ret = IRQ_NONE;
1314f5473692STali Perry u8 i2cst = ioread8(bus->reg + NPCM_I2CST);
1315f5473692STali Perry
1316f5473692STali Perry /* Slave: A NACK has occurred */
1317f5473692STali Perry if (NPCM_I2CST_NEGACK & i2cst) {
1318f5473692STali Perry bus->stop_ind = I2C_NACK_IND;
1319f5473692STali Perry npcm_i2c_slave_wr_buf_sync(bus);
1320f5473692STali Perry if (bus->fifo_use)
1321f5473692STali Perry /* clear the FIFO */
1322f5473692STali Perry iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO,
1323f5473692STali Perry bus->reg + NPCM_I2CFIF_CTS);
1324f5473692STali Perry
1325f5473692STali Perry /* In slave write, NACK is OK, otherwise it is a problem */
1326f5473692STali Perry bus->stop_ind = I2C_NO_STATUS_IND;
1327f5473692STali Perry bus->operation = I2C_NO_OPER;
1328f5473692STali Perry bus->own_slave_addr = 0xFF;
1329f5473692STali Perry
1330f5473692STali Perry /*
1331f5473692STali Perry * Slave has to wait for STOP to decide this is the end
1332f5473692STali Perry * of the transaction. tx is not yet considered as done
1333f5473692STali Perry */
1334f5473692STali Perry iowrite8(NPCM_I2CST_NEGACK, bus->reg + NPCM_I2CST);
1335f5473692STali Perry
1336f5473692STali Perry ret = IRQ_HANDLED;
1337f5473692STali Perry }
1338f5473692STali Perry
1339f5473692STali Perry /* Slave mode: a Bus Error (BER) has been identified */
1340f5473692STali Perry if (NPCM_I2CST_BER & i2cst) {
1341f5473692STali Perry /*
1342f5473692STali Perry * Check whether bus arbitration or Start or Stop during data
1343f5473692STali Perry * xfer bus arbitration problem should not result in recovery
1344f5473692STali Perry */
1345f5473692STali Perry bus->stop_ind = I2C_BUS_ERR_IND;
1346f5473692STali Perry
1347f5473692STali Perry /* wait for bus busy before clear fifo */
1348f5473692STali Perry iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS);
1349f5473692STali Perry
1350f5473692STali Perry bus->state = I2C_IDLE;
1351f5473692STali Perry
1352f5473692STali Perry /*
1353f5473692STali Perry * in BER case we might get 2 interrupts: one for slave one for
1354f5473692STali Perry * master ( for a channel which is master\slave switching)
1355f5473692STali Perry */
1356f5473692STali Perry if (completion_done(&bus->cmd_complete) == false) {
1357f5473692STali Perry bus->cmd_err = -EIO;
1358f5473692STali Perry complete(&bus->cmd_complete);
1359f5473692STali Perry }
1360f5473692STali Perry bus->own_slave_addr = 0xFF;
1361f5473692STali Perry iowrite8(NPCM_I2CST_BER, bus->reg + NPCM_I2CST);
1362f5473692STali Perry ret = IRQ_HANDLED;
1363f5473692STali Perry }
1364f5473692STali Perry
1365f5473692STali Perry /* A Slave Stop Condition has been identified */
1366f5473692STali Perry if (NPCM_I2CST_SLVSTP & i2cst) {
1367f5473692STali Perry u8 bytes_in_fifo = npcm_i2c_fifo_usage(bus);
1368f5473692STali Perry
1369f5473692STali Perry bus->stop_ind = I2C_SLAVE_DONE_IND;
1370f5473692STali Perry
1371f5473692STali Perry if (bus->operation == I2C_READ_OPER)
1372f5473692STali Perry npcm_i2c_read_fifo_slave(bus, bytes_in_fifo);
1373f5473692STali Perry
1374f5473692STali Perry /* if the buffer is empty nothing will be sent */
1375f5473692STali Perry npcm_i2c_slave_send_rd_buf(bus);
1376f5473692STali Perry
1377f5473692STali Perry /* Slave done transmitting or receiving */
1378f5473692STali Perry bus->stop_ind = I2C_NO_STATUS_IND;
1379f5473692STali Perry
1380f5473692STali Perry /*
1381f5473692STali Perry * Note, just because we got here, it doesn't mean we through
1382f5473692STali Perry * away the wr buffer.
1383f5473692STali Perry * we keep it until the next received offset.
1384f5473692STali Perry */
1385f5473692STali Perry bus->operation = I2C_NO_OPER;
1386f5473692STali Perry bus->own_slave_addr = 0xFF;
1387f5473692STali Perry i2c_slave_event(bus->slave, I2C_SLAVE_STOP, 0);
1388f5473692STali Perry iowrite8(NPCM_I2CST_SLVSTP, bus->reg + NPCM_I2CST);
1389f5473692STali Perry if (bus->fifo_use) {
1390f5473692STali Perry npcm_i2c_clear_fifo_int(bus);
1391f5473692STali Perry npcm_i2c_clear_rx_fifo(bus);
1392f5473692STali Perry npcm_i2c_clear_tx_fifo(bus);
1393f5473692STali Perry
1394f5473692STali Perry iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO,
1395f5473692STali Perry bus->reg + NPCM_I2CFIF_CTS);
1396f5473692STali Perry }
1397f5473692STali Perry bus->state = I2C_IDLE;
1398f5473692STali Perry ret = IRQ_HANDLED;
1399f5473692STali Perry }
1400f5473692STali Perry
1401f5473692STali Perry /* restart condition occurred and Rx-FIFO was not empty */
1402f5473692STali Perry if (bus->fifo_use && FIELD_GET(NPCM_I2CFIF_CTS_SLVRSTR,
1403f5473692STali Perry ioread8(bus->reg + NPCM_I2CFIF_CTS))) {
1404f5473692STali Perry bus->stop_ind = I2C_SLAVE_RESTART_IND;
1405f5473692STali Perry bus->master_or_slave = I2C_SLAVE;
1406f5473692STali Perry if (bus->operation == I2C_READ_OPER)
1407f5473692STali Perry npcm_i2c_read_fifo_slave(bus, npcm_i2c_fifo_usage(bus));
1408f5473692STali Perry bus->operation = I2C_WRITE_OPER;
1409f5473692STali Perry iowrite8(0, bus->reg + NPCM_I2CRXF_CTL);
1410f5473692STali Perry val = NPCM_I2CFIF_CTS_CLR_FIFO | NPCM_I2CFIF_CTS_SLVRSTR |
1411f5473692STali Perry NPCM_I2CFIF_CTS_RXF_TXE;
1412f5473692STali Perry iowrite8(val, bus->reg + NPCM_I2CFIF_CTS);
1413f5473692STali Perry npcm_i2c_slave_rd_wr(bus);
1414f5473692STali Perry ret = IRQ_HANDLED;
1415f5473692STali Perry }
1416f5473692STali Perry
1417f5473692STali Perry /* A Slave Address Match has been identified */
1418f5473692STali Perry if (NPCM_I2CST_NMATCH & i2cst) {
1419f5473692STali Perry u8 info = 0;
1420f5473692STali Perry
1421f5473692STali Perry /* Address match automatically implies slave mode */
1422f5473692STali Perry bus->master_or_slave = I2C_SLAVE;
1423f5473692STali Perry npcm_i2c_clear_fifo_int(bus);
1424f5473692STali Perry npcm_i2c_clear_rx_fifo(bus);
1425f5473692STali Perry npcm_i2c_clear_tx_fifo(bus);
1426f5473692STali Perry iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
1427bbc38ed5STyrone Ting iowrite8(bus->data->fifo_size, bus->reg + NPCM_I2CRXF_CTL);
1428f5473692STali Perry if (NPCM_I2CST_XMIT & i2cst) {
1429f5473692STali Perry bus->operation = I2C_WRITE_OPER;
1430f5473692STali Perry } else {
1431f5473692STali Perry i2c_slave_event(bus->slave, I2C_SLAVE_WRITE_REQUESTED,
1432f5473692STali Perry &info);
1433f5473692STali Perry bus->operation = I2C_READ_OPER;
1434f5473692STali Perry }
1435f5473692STali Perry if (bus->own_slave_addr == 0xFF) {
1436f5473692STali Perry /* Check which type of address match */
1437f5473692STali Perry val = ioread8(bus->reg + NPCM_I2CCST);
1438f5473692STali Perry if (NPCM_I2CCST_MATCH & val) {
1439f5473692STali Perry u16 addr;
1440f5473692STali Perry enum i2c_addr eaddr;
1441f5473692STali Perry u8 i2ccst2;
1442f5473692STali Perry u8 i2ccst3;
1443f5473692STali Perry
1444f5473692STali Perry i2ccst3 = ioread8(bus->reg + NPCM_I2CCST3);
1445f5473692STali Perry i2ccst2 = ioread8(bus->reg + NPCM_I2CCST2);
1446f5473692STali Perry
1447f5473692STali Perry /*
1448f5473692STali Perry * the i2c module can response to 10 own SA.
1449f5473692STali Perry * check which one was addressed by the master.
14500c47dd7dSJonathan Neuschäfer * respond to the first one.
1451f5473692STali Perry */
1452f5473692STali Perry addr = ((i2ccst3 & 0x07) << 7) |
1453f5473692STali Perry (i2ccst2 & 0x7F);
1454f5473692STali Perry info = ffs(addr);
1455f5473692STali Perry eaddr = (enum i2c_addr)info;
1456f5473692STali Perry addr = npcm_i2c_get_slave_addr(bus, eaddr);
1457f5473692STali Perry addr &= 0x7F;
1458f5473692STali Perry bus->own_slave_addr = addr;
1459f5473692STali Perry if (bus->PEC_mask & BIT(info))
1460f5473692STali Perry bus->PEC_use = true;
1461f5473692STali Perry else
1462f5473692STali Perry bus->PEC_use = false;
1463f5473692STali Perry } else {
1464f5473692STali Perry if (NPCM_I2CCST_GCMATCH & val)
1465f5473692STali Perry bus->own_slave_addr = 0;
1466f5473692STali Perry if (NPCM_I2CCST_ARPMATCH & val)
1467f5473692STali Perry bus->own_slave_addr = 0x61;
1468f5473692STali Perry }
1469f5473692STali Perry } else {
1470f5473692STali Perry /*
1471f5473692STali Perry * Slave match can happen in two options:
1472f5473692STali Perry * 1. Start, SA, read (slave read without further ado)
1473f5473692STali Perry * 2. Start, SA, read, data, restart, SA, read, ...
1474f5473692STali Perry * (slave read in fragmented mode)
1475f5473692STali Perry * 3. Start, SA, write, data, restart, SA, read, ..
1476f5473692STali Perry * (regular write-read mode)
1477f5473692STali Perry */
1478f5473692STali Perry if ((bus->state == I2C_OPER_STARTED &&
1479f5473692STali Perry bus->operation == I2C_READ_OPER &&
1480f5473692STali Perry bus->stop_ind == I2C_SLAVE_XMIT_IND) ||
1481f5473692STali Perry bus->stop_ind == I2C_SLAVE_RCV_IND) {
1482f5473692STali Perry /* slave tx after slave rx w/o STOP */
1483f5473692STali Perry bus->stop_ind = I2C_SLAVE_RESTART_IND;
1484f5473692STali Perry }
1485f5473692STali Perry }
1486f5473692STali Perry
1487f5473692STali Perry if (NPCM_I2CST_XMIT & i2cst)
1488f5473692STali Perry bus->stop_ind = I2C_SLAVE_XMIT_IND;
1489f5473692STali Perry else
1490f5473692STali Perry bus->stop_ind = I2C_SLAVE_RCV_IND;
1491f5473692STali Perry bus->state = I2C_SLAVE_MATCH;
1492f5473692STali Perry npcm_i2c_slave_rd_wr(bus);
1493f5473692STali Perry iowrite8(NPCM_I2CST_NMATCH, bus->reg + NPCM_I2CST);
1494f5473692STali Perry ret = IRQ_HANDLED;
1495f5473692STali Perry }
1496f5473692STali Perry
1497f5473692STali Perry /* Slave SDA status is set - tx or rx */
1498f5473692STali Perry if ((NPCM_I2CST_SDAST & i2cst) ||
1499f5473692STali Perry (bus->fifo_use &&
1500f5473692STali Perry (npcm_i2c_tx_fifo_empty(bus) || npcm_i2c_rx_fifo_full(bus)))) {
1501f5473692STali Perry npcm_i2c_slave_rd_wr(bus);
1502f5473692STali Perry iowrite8(NPCM_I2CST_SDAST, bus->reg + NPCM_I2CST);
1503f5473692STali Perry ret = IRQ_HANDLED;
1504f5473692STali Perry } /* SDAST */
1505f5473692STali Perry
1506e5222d40STali Perry /*
1507ffad0a35STyrone Ting * If irq is not one of the above, make sure EOB is disabled and all
1508e5222d40STali Perry * status bits are cleared.
1509e5222d40STali Perry */
1510e5222d40STali Perry if (ret == IRQ_NONE) {
1511e5222d40STali Perry npcm_i2c_eob_int(bus, false);
1512e5222d40STali Perry npcm_i2c_clear_master_status(bus);
1513e5222d40STali Perry }
1514e5222d40STali Perry
1515e5222d40STali Perry return IRQ_HANDLED;
1516f5473692STali Perry }
1517f5473692STali Perry
npcm_i2c_reg_slave(struct i2c_client * client)1518f5473692STali Perry static int npcm_i2c_reg_slave(struct i2c_client *client)
1519f5473692STali Perry {
1520f5473692STali Perry unsigned long lock_flags;
1521f5473692STali Perry struct npcm_i2c *bus = i2c_get_adapdata(client->adapter);
1522f5473692STali Perry
1523f5473692STali Perry bus->slave = client;
1524f5473692STali Perry
1525f5473692STali Perry if (client->flags & I2C_CLIENT_TEN)
1526f5473692STali Perry return -EAFNOSUPPORT;
1527f5473692STali Perry
1528f5473692STali Perry spin_lock_irqsave(&bus->lock, lock_flags);
1529f5473692STali Perry
1530f5473692STali Perry npcm_i2c_init_params(bus);
1531f5473692STali Perry bus->slv_rd_size = 0;
1532f5473692STali Perry bus->slv_wr_size = 0;
1533f5473692STali Perry bus->slv_rd_ind = 0;
1534f5473692STali Perry bus->slv_wr_ind = 0;
1535f5473692STali Perry if (client->flags & I2C_CLIENT_PEC)
1536f5473692STali Perry bus->PEC_use = true;
1537f5473692STali Perry
1538f5473692STali Perry dev_info(bus->dev, "i2c%d register slave SA=0x%x, PEC=%d\n", bus->num,
1539f5473692STali Perry client->addr, bus->PEC_use);
1540f5473692STali Perry
1541f5473692STali Perry npcm_i2c_slave_enable(bus, I2C_SLAVE_ADDR1, client->addr, true);
1542f5473692STali Perry npcm_i2c_clear_fifo_int(bus);
1543f5473692STali Perry npcm_i2c_clear_rx_fifo(bus);
1544f5473692STali Perry npcm_i2c_clear_tx_fifo(bus);
1545f5473692STali Perry npcm_i2c_slave_int_enable(bus, true);
1546f5473692STali Perry
1547f5473692STali Perry spin_unlock_irqrestore(&bus->lock, lock_flags);
1548f5473692STali Perry return 0;
1549f5473692STali Perry }
1550f5473692STali Perry
npcm_i2c_unreg_slave(struct i2c_client * client)1551f5473692STali Perry static int npcm_i2c_unreg_slave(struct i2c_client *client)
1552f5473692STali Perry {
1553f5473692STali Perry struct npcm_i2c *bus = client->adapter->algo_data;
1554f5473692STali Perry unsigned long lock_flags;
1555f5473692STali Perry
1556f5473692STali Perry spin_lock_irqsave(&bus->lock, lock_flags);
1557f5473692STali Perry if (!bus->slave) {
1558f5473692STali Perry spin_unlock_irqrestore(&bus->lock, lock_flags);
1559f5473692STali Perry return -EINVAL;
1560f5473692STali Perry }
1561f5473692STali Perry npcm_i2c_slave_int_enable(bus, false);
1562f5473692STali Perry npcm_i2c_remove_slave_addr(bus, client->addr);
1563f5473692STali Perry bus->slave = NULL;
1564f5473692STali Perry spin_unlock_irqrestore(&bus->lock, lock_flags);
1565f5473692STali Perry return 0;
1566f5473692STali Perry }
1567f5473692STali Perry #endif /* CONFIG_I2C_SLAVE */
1568f5473692STali Perry
npcm_i2c_master_fifo_read(struct npcm_i2c * bus)156956a1485bSTali Perry static void npcm_i2c_master_fifo_read(struct npcm_i2c *bus)
157056a1485bSTali Perry {
157156a1485bSTali Perry int rcount;
157256a1485bSTali Perry int fifo_bytes;
157356a1485bSTali Perry enum i2c_state_ind ind = I2C_MASTER_DONE_IND;
157456a1485bSTali Perry
157556a1485bSTali Perry fifo_bytes = npcm_i2c_fifo_usage(bus);
157656a1485bSTali Perry rcount = bus->rd_size - bus->rd_ind;
157756a1485bSTali Perry
157856a1485bSTali Perry /*
157956a1485bSTali Perry * In order not to change the RX_TRH during transaction (we found that
158056a1485bSTali Perry * this might be problematic if it takes too much time to read the FIFO)
158156a1485bSTali Perry * we read the data in the following way. If the number of bytes to
158256a1485bSTali Perry * read == FIFO Size + C (where C < FIFO Size)then first read C bytes
158356a1485bSTali Perry * and in the next int we read rest of the data.
158456a1485bSTali Perry */
1585bbc38ed5STyrone Ting if (rcount < (2 * bus->data->fifo_size) && rcount > bus->data->fifo_size)
1586bbc38ed5STyrone Ting fifo_bytes = rcount - bus->data->fifo_size;
158756a1485bSTali Perry
158856a1485bSTali Perry if (rcount <= fifo_bytes) {
158956a1485bSTali Perry /* last bytes are about to be read - end of tx */
159056a1485bSTali Perry bus->state = I2C_STOP_PENDING;
159156a1485bSTali Perry bus->stop_ind = ind;
159256a1485bSTali Perry npcm_i2c_eob_int(bus, true);
159356a1485bSTali Perry /* Stop should be set before reading last byte. */
159456a1485bSTali Perry npcm_i2c_master_stop(bus);
159556a1485bSTali Perry npcm_i2c_read_fifo(bus, fifo_bytes);
159656a1485bSTali Perry } else {
159756a1485bSTali Perry npcm_i2c_read_fifo(bus, fifo_bytes);
159856a1485bSTali Perry rcount = bus->rd_size - bus->rd_ind;
159956a1485bSTali Perry npcm_i2c_set_fifo(bus, rcount, -1);
160056a1485bSTali Perry }
160156a1485bSTali Perry }
160256a1485bSTali Perry
npcm_i2c_irq_master_handler_write(struct npcm_i2c * bus)160356a1485bSTali Perry static void npcm_i2c_irq_master_handler_write(struct npcm_i2c *bus)
160456a1485bSTali Perry {
160556a1485bSTali Perry u16 wcount;
160656a1485bSTali Perry
160756a1485bSTali Perry if (bus->fifo_use)
160856a1485bSTali Perry npcm_i2c_clear_tx_fifo(bus); /* clear the TX fifo status bit */
160956a1485bSTali Perry
161056a1485bSTali Perry /* Master write operation - last byte handling */
161156a1485bSTali Perry if (bus->wr_ind == bus->wr_size) {
161256a1485bSTali Perry if (bus->fifo_use && npcm_i2c_fifo_usage(bus) > 0)
161356a1485bSTali Perry /*
161456a1485bSTali Perry * No more bytes to send (to add to the FIFO),
161556a1485bSTali Perry * however the FIFO is not empty yet. It is
161656a1485bSTali Perry * still in the middle of tx. Currently there's nothing
161756a1485bSTali Perry * to do except for waiting to the end of the tx
161856a1485bSTali Perry * We will get an int when the FIFO will get empty.
161956a1485bSTali Perry */
162056a1485bSTali Perry return;
162156a1485bSTali Perry
162256a1485bSTali Perry if (bus->rd_size == 0) {
162356a1485bSTali Perry /* all bytes have been written, in wr only operation */
162456a1485bSTali Perry npcm_i2c_eob_int(bus, true);
162556a1485bSTali Perry bus->state = I2C_STOP_PENDING;
162656a1485bSTali Perry bus->stop_ind = I2C_MASTER_DONE_IND;
162756a1485bSTali Perry npcm_i2c_master_stop(bus);
162856a1485bSTali Perry /* Clear SDA Status bit (by writing dummy byte) */
162956a1485bSTali Perry npcm_i2c_wr_byte(bus, 0xFF);
163056a1485bSTali Perry
163156a1485bSTali Perry } else {
163256a1485bSTali Perry /* last write-byte written on previous int - restart */
163356a1485bSTali Perry npcm_i2c_set_fifo(bus, bus->rd_size, -1);
163456a1485bSTali Perry /* Generate repeated start upon next write to SDA */
163556a1485bSTali Perry npcm_i2c_master_start(bus);
163656a1485bSTali Perry
163756a1485bSTali Perry /*
163856a1485bSTali Perry * Receiving one byte only - stall after successful
163956a1485bSTali Perry * completion of send address byte. If we NACK here, and
164056a1485bSTali Perry * slave doesn't ACK the address, we might
164156a1485bSTali Perry * unintentionally NACK the next multi-byte read.
164256a1485bSTali Perry */
164356a1485bSTali Perry if (bus->rd_size == 1)
164456a1485bSTali Perry npcm_i2c_stall_after_start(bus, true);
164556a1485bSTali Perry
164656a1485bSTali Perry /* Next int will occur on read */
164756a1485bSTali Perry bus->operation = I2C_READ_OPER;
164856a1485bSTali Perry /* send the slave address in read direction */
164956a1485bSTali Perry npcm_i2c_wr_byte(bus, bus->dest_addr | 0x1);
165056a1485bSTali Perry }
165156a1485bSTali Perry } else {
165256a1485bSTali Perry /* write next byte not last byte and not slave address */
165356a1485bSTali Perry if (!bus->fifo_use || bus->wr_size == 1) {
165456a1485bSTali Perry npcm_i2c_wr_byte(bus, bus->wr_buf[bus->wr_ind++]);
165556a1485bSTali Perry } else {
165656a1485bSTali Perry wcount = bus->wr_size - bus->wr_ind;
165756a1485bSTali Perry npcm_i2c_set_fifo(bus, -1, wcount);
165856a1485bSTali Perry if (wcount)
165956a1485bSTali Perry npcm_i2c_write_to_fifo_master(bus, wcount);
166056a1485bSTali Perry }
166156a1485bSTali Perry }
166256a1485bSTali Perry }
166356a1485bSTali Perry
npcm_i2c_irq_master_handler_read(struct npcm_i2c * bus)166456a1485bSTali Perry static void npcm_i2c_irq_master_handler_read(struct npcm_i2c *bus)
166556a1485bSTali Perry {
166656a1485bSTali Perry u16 block_extra_bytes_size;
166756a1485bSTali Perry u8 data;
166856a1485bSTali Perry
166956a1485bSTali Perry /* added bytes to the packet: */
167056a1485bSTali Perry block_extra_bytes_size = bus->read_block_use + bus->PEC_use;
167156a1485bSTali Perry
167256a1485bSTali Perry /*
167356a1485bSTali Perry * Perform master read, distinguishing between last byte and the rest of
167456a1485bSTali Perry * the bytes. The last byte should be read when the clock is stopped
167556a1485bSTali Perry */
167656a1485bSTali Perry if (bus->rd_ind == 0) { /* first byte handling: */
167756a1485bSTali Perry if (bus->read_block_use) {
167856a1485bSTali Perry /* first byte in block protocol is the size: */
167956a1485bSTali Perry data = npcm_i2c_rd_byte(bus);
168056a1485bSTali Perry data = clamp_val(data, 1, I2C_SMBUS_BLOCK_MAX);
168156a1485bSTali Perry bus->rd_size = data + block_extra_bytes_size;
168256a1485bSTali Perry bus->rd_buf[bus->rd_ind++] = data;
168356a1485bSTali Perry
168456a1485bSTali Perry /* clear RX FIFO interrupt status: */
168556a1485bSTali Perry if (bus->fifo_use) {
168656a1485bSTali Perry data = ioread8(bus->reg + NPCM_I2CFIF_CTS);
168756a1485bSTali Perry data = data | NPCM_I2CFIF_CTS_RXF_TXE;
168856a1485bSTali Perry iowrite8(data, bus->reg + NPCM_I2CFIF_CTS);
168956a1485bSTali Perry }
169056a1485bSTali Perry
169156a1485bSTali Perry npcm_i2c_set_fifo(bus, bus->rd_size - 1, -1);
169256a1485bSTali Perry npcm_i2c_stall_after_start(bus, false);
169356a1485bSTali Perry } else {
169456a1485bSTali Perry npcm_i2c_clear_tx_fifo(bus);
169556a1485bSTali Perry npcm_i2c_master_fifo_read(bus);
169656a1485bSTali Perry }
169756a1485bSTali Perry } else {
169856a1485bSTali Perry if (bus->rd_size == block_extra_bytes_size &&
169956a1485bSTali Perry bus->read_block_use) {
170056a1485bSTali Perry bus->state = I2C_STOP_PENDING;
170156a1485bSTali Perry bus->stop_ind = I2C_BLOCK_BYTES_ERR_IND;
170256a1485bSTali Perry bus->cmd_err = -EIO;
170356a1485bSTali Perry npcm_i2c_eob_int(bus, true);
170456a1485bSTali Perry npcm_i2c_master_stop(bus);
170556a1485bSTali Perry npcm_i2c_read_fifo(bus, npcm_i2c_fifo_usage(bus));
170656a1485bSTali Perry } else {
170756a1485bSTali Perry npcm_i2c_master_fifo_read(bus);
170856a1485bSTali Perry }
170956a1485bSTali Perry }
171056a1485bSTali Perry }
171156a1485bSTali Perry
npcm_i2c_irq_handle_nmatch(struct npcm_i2c * bus)171256a1485bSTali Perry static void npcm_i2c_irq_handle_nmatch(struct npcm_i2c *bus)
171356a1485bSTali Perry {
171456a1485bSTali Perry iowrite8(NPCM_I2CST_NMATCH, bus->reg + NPCM_I2CST);
171556a1485bSTali Perry npcm_i2c_nack(bus);
171656a1485bSTali Perry bus->stop_ind = I2C_BUS_ERR_IND;
171756a1485bSTali Perry npcm_i2c_callback(bus, bus->stop_ind, npcm_i2c_get_index(bus));
171856a1485bSTali Perry }
171956a1485bSTali Perry
172056a1485bSTali Perry /* A NACK has occurred */
npcm_i2c_irq_handle_nack(struct npcm_i2c * bus)172156a1485bSTali Perry static void npcm_i2c_irq_handle_nack(struct npcm_i2c *bus)
172256a1485bSTali Perry {
172356a1485bSTali Perry u8 val;
172456a1485bSTali Perry
172556a1485bSTali Perry if (bus->nack_cnt < ULLONG_MAX)
172656a1485bSTali Perry bus->nack_cnt++;
172756a1485bSTali Perry
172856a1485bSTali Perry if (bus->fifo_use) {
172956a1485bSTali Perry /*
173056a1485bSTali Perry * if there are still untransmitted bytes in TX FIFO
173156a1485bSTali Perry * reduce them from wr_ind
173256a1485bSTali Perry */
173356a1485bSTali Perry if (bus->operation == I2C_WRITE_OPER)
173456a1485bSTali Perry bus->wr_ind -= npcm_i2c_fifo_usage(bus);
173556a1485bSTali Perry
173656a1485bSTali Perry /* clear the FIFO */
173756a1485bSTali Perry iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS);
173856a1485bSTali Perry }
173956a1485bSTali Perry
174056a1485bSTali Perry /* In master write operation, got unexpected NACK */
174156a1485bSTali Perry bus->stop_ind = I2C_NACK_IND;
174256a1485bSTali Perry /* Only current master is allowed to issue Stop Condition */
174356a1485bSTali Perry if (npcm_i2c_is_master(bus)) {
174456a1485bSTali Perry /* stopping in the middle */
174556a1485bSTali Perry npcm_i2c_eob_int(bus, false);
174656a1485bSTali Perry npcm_i2c_master_stop(bus);
174756a1485bSTali Perry
1748e5222d40STali Perry /* Clear SDA Status bit (by reading dummy byte) */
1749e5222d40STali Perry npcm_i2c_rd_byte(bus);
1750e5222d40STali Perry
175156a1485bSTali Perry /*
175256a1485bSTali Perry * The bus is released from stall only after the SW clears
175356a1485bSTali Perry * NEGACK bit. Then a Stop condition is sent.
175456a1485bSTali Perry */
175556a1485bSTali Perry npcm_i2c_clear_master_status(bus);
175656a1485bSTali Perry readx_poll_timeout_atomic(ioread8, bus->reg + NPCM_I2CCST, val,
175756a1485bSTali Perry !(val & NPCM_I2CCST_BUSY), 10, 200);
1758ffad0a35STyrone Ting /* Verify no status bits are still set after bus is released */
1759e5222d40STali Perry npcm_i2c_clear_master_status(bus);
176056a1485bSTali Perry }
176156a1485bSTali Perry bus->state = I2C_IDLE;
176256a1485bSTali Perry
176356a1485bSTali Perry /*
176456a1485bSTali Perry * In Master mode, NACK should be cleared only after STOP.
176556a1485bSTali Perry * In such case, the bus is released from stall only after the
176656a1485bSTali Perry * software clears NACK bit. Then a Stop condition is sent.
176756a1485bSTali Perry */
176856a1485bSTali Perry npcm_i2c_callback(bus, bus->stop_ind, bus->wr_ind);
176956a1485bSTali Perry }
177056a1485bSTali Perry
177156a1485bSTali Perry /* Master mode: a Bus Error has been identified */
npcm_i2c_irq_handle_ber(struct npcm_i2c * bus)177256a1485bSTali Perry static void npcm_i2c_irq_handle_ber(struct npcm_i2c *bus)
177356a1485bSTali Perry {
177456a1485bSTali Perry if (bus->ber_cnt < ULLONG_MAX)
177556a1485bSTali Perry bus->ber_cnt++;
177656a1485bSTali Perry bus->stop_ind = I2C_BUS_ERR_IND;
177756a1485bSTali Perry if (npcm_i2c_is_master(bus)) {
177856a1485bSTali Perry npcm_i2c_master_abort(bus);
177956a1485bSTali Perry } else {
1780b0118105STyrone Ting bus->ber_state = true;
178156a1485bSTali Perry npcm_i2c_clear_master_status(bus);
178256a1485bSTali Perry
178356a1485bSTali Perry /* Clear BB (BUS BUSY) bit */
178456a1485bSTali Perry iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
178556a1485bSTali Perry
178656a1485bSTali Perry bus->cmd_err = -EAGAIN;
178756a1485bSTali Perry npcm_i2c_callback(bus, bus->stop_ind, npcm_i2c_get_index(bus));
178856a1485bSTali Perry }
178956a1485bSTali Perry bus->state = I2C_IDLE;
179056a1485bSTali Perry }
179156a1485bSTali Perry
179256a1485bSTali Perry /* EOB: a master End Of Busy (meaning STOP completed) */
npcm_i2c_irq_handle_eob(struct npcm_i2c * bus)179356a1485bSTali Perry static void npcm_i2c_irq_handle_eob(struct npcm_i2c *bus)
179456a1485bSTali Perry {
179556a1485bSTali Perry npcm_i2c_eob_int(bus, false);
179656a1485bSTali Perry bus->state = I2C_IDLE;
179756a1485bSTali Perry npcm_i2c_callback(bus, bus->stop_ind, bus->rd_ind);
179856a1485bSTali Perry }
179956a1485bSTali Perry
180056a1485bSTali Perry /* Address sent and requested stall occurred (Master mode) */
npcm_i2c_irq_handle_stall_after_start(struct npcm_i2c * bus)180156a1485bSTali Perry static void npcm_i2c_irq_handle_stall_after_start(struct npcm_i2c *bus)
180256a1485bSTali Perry {
180356a1485bSTali Perry if (npcm_i2c_is_quick(bus)) {
180456a1485bSTali Perry bus->state = I2C_STOP_PENDING;
180556a1485bSTali Perry bus->stop_ind = I2C_MASTER_DONE_IND;
180656a1485bSTali Perry npcm_i2c_eob_int(bus, true);
180756a1485bSTali Perry npcm_i2c_master_stop(bus);
180856a1485bSTali Perry } else if ((bus->rd_size == 1) && !bus->read_block_use) {
180956a1485bSTali Perry /*
181056a1485bSTali Perry * Receiving one byte only - set NACK after ensuring
181156a1485bSTali Perry * slave ACKed the address byte.
181256a1485bSTali Perry */
181356a1485bSTali Perry npcm_i2c_nack(bus);
181456a1485bSTali Perry }
181556a1485bSTali Perry
181656a1485bSTali Perry /* Reset stall-after-address-byte */
181756a1485bSTali Perry npcm_i2c_stall_after_start(bus, false);
181856a1485bSTali Perry
181956a1485bSTali Perry /* Clear stall only after setting STOP */
182056a1485bSTali Perry iowrite8(NPCM_I2CST_STASTR, bus->reg + NPCM_I2CST);
182156a1485bSTali Perry }
182256a1485bSTali Perry
182356a1485bSTali Perry /* SDA status is set - TX or RX, master */
npcm_i2c_irq_handle_sda(struct npcm_i2c * bus,u8 i2cst)182456a1485bSTali Perry static void npcm_i2c_irq_handle_sda(struct npcm_i2c *bus, u8 i2cst)
182556a1485bSTali Perry {
182656a1485bSTali Perry u8 fif_cts;
182756a1485bSTali Perry
182856a1485bSTali Perry if (!npcm_i2c_is_master(bus))
182956a1485bSTali Perry return;
183056a1485bSTali Perry
183156a1485bSTali Perry if (bus->state == I2C_IDLE) {
183256a1485bSTali Perry bus->stop_ind = I2C_WAKE_UP_IND;
183356a1485bSTali Perry
183456a1485bSTali Perry if (npcm_i2c_is_quick(bus) || bus->read_block_use)
183556a1485bSTali Perry /*
183656a1485bSTali Perry * Need to stall after successful
183756a1485bSTali Perry * completion of sending address byte
183856a1485bSTali Perry */
183956a1485bSTali Perry npcm_i2c_stall_after_start(bus, true);
184056a1485bSTali Perry else
184156a1485bSTali Perry npcm_i2c_stall_after_start(bus, false);
184256a1485bSTali Perry
184356a1485bSTali Perry /*
184456a1485bSTali Perry * Receiving one byte only - stall after successful completion
184556a1485bSTali Perry * of sending address byte If we NACK here, and slave doesn't
184656a1485bSTali Perry * ACK the address, we might unintentionally NACK the next
184756a1485bSTali Perry * multi-byte read
184856a1485bSTali Perry */
184956a1485bSTali Perry if (bus->wr_size == 0 && bus->rd_size == 1)
185056a1485bSTali Perry npcm_i2c_stall_after_start(bus, true);
185156a1485bSTali Perry
185256a1485bSTali Perry /* Initiate I2C master tx */
185356a1485bSTali Perry
185456a1485bSTali Perry /* select bank 1 for FIFO regs */
185556a1485bSTali Perry npcm_i2c_select_bank(bus, I2C_BANK_1);
185656a1485bSTali Perry
185756a1485bSTali Perry fif_cts = ioread8(bus->reg + NPCM_I2CFIF_CTS);
185856a1485bSTali Perry fif_cts = fif_cts & ~NPCM_I2CFIF_CTS_SLVRSTR;
185956a1485bSTali Perry
186056a1485bSTali Perry /* clear FIFO and relevant status bits. */
186156a1485bSTali Perry fif_cts = fif_cts | NPCM_I2CFIF_CTS_CLR_FIFO;
186256a1485bSTali Perry iowrite8(fif_cts, bus->reg + NPCM_I2CFIF_CTS);
186356a1485bSTali Perry
186456a1485bSTali Perry /* re-enable */
186556a1485bSTali Perry fif_cts = fif_cts | NPCM_I2CFIF_CTS_RXF_TXE;
186656a1485bSTali Perry iowrite8(fif_cts, bus->reg + NPCM_I2CFIF_CTS);
186756a1485bSTali Perry
186856a1485bSTali Perry /*
186956a1485bSTali Perry * Configure the FIFO threshold:
187056a1485bSTali Perry * according to the needed # of bytes to read.
187156a1485bSTali Perry * Note: due to HW limitation can't config the rx fifo before it
187256a1485bSTali Perry * got and ACK on the restart. LAST bit will not be reset unless
187356a1485bSTali Perry * RX completed. It will stay set on the next tx.
187456a1485bSTali Perry */
187556a1485bSTali Perry if (bus->wr_size)
187656a1485bSTali Perry npcm_i2c_set_fifo(bus, -1, bus->wr_size);
187756a1485bSTali Perry else
187856a1485bSTali Perry npcm_i2c_set_fifo(bus, bus->rd_size, -1);
187956a1485bSTali Perry
188056a1485bSTali Perry bus->state = I2C_OPER_STARTED;
188156a1485bSTali Perry
188256a1485bSTali Perry if (npcm_i2c_is_quick(bus) || bus->wr_size)
188356a1485bSTali Perry npcm_i2c_wr_byte(bus, bus->dest_addr);
188456a1485bSTali Perry else
188556a1485bSTali Perry npcm_i2c_wr_byte(bus, bus->dest_addr | BIT(0));
188656a1485bSTali Perry /* SDA interrupt, after start\restart */
188756a1485bSTali Perry } else {
1888e365422cSTyrone Ting if (bus->operation == I2C_WRITE_OPER)
188956a1485bSTali Perry npcm_i2c_irq_master_handler_write(bus);
1890e365422cSTyrone Ting else if (bus->operation == I2C_READ_OPER)
189156a1485bSTali Perry npcm_i2c_irq_master_handler_read(bus);
189256a1485bSTali Perry }
189356a1485bSTali Perry }
189456a1485bSTali Perry
npcm_i2c_int_master_handler(struct npcm_i2c * bus)189556a1485bSTali Perry static int npcm_i2c_int_master_handler(struct npcm_i2c *bus)
189656a1485bSTali Perry {
189756a1485bSTali Perry u8 i2cst;
189856a1485bSTali Perry int ret = -EIO;
189956a1485bSTali Perry
190056a1485bSTali Perry i2cst = ioread8(bus->reg + NPCM_I2CST);
190156a1485bSTali Perry
190256a1485bSTali Perry if (FIELD_GET(NPCM_I2CST_NMATCH, i2cst)) {
190356a1485bSTali Perry npcm_i2c_irq_handle_nmatch(bus);
190456a1485bSTali Perry return 0;
190556a1485bSTali Perry }
190656a1485bSTali Perry /* A NACK has occurred */
190756a1485bSTali Perry if (FIELD_GET(NPCM_I2CST_NEGACK, i2cst)) {
190856a1485bSTali Perry npcm_i2c_irq_handle_nack(bus);
190956a1485bSTali Perry return 0;
191056a1485bSTali Perry }
191156a1485bSTali Perry
191256a1485bSTali Perry /* Master mode: a Bus Error has been identified */
191356a1485bSTali Perry if (FIELD_GET(NPCM_I2CST_BER, i2cst)) {
191456a1485bSTali Perry npcm_i2c_irq_handle_ber(bus);
191556a1485bSTali Perry return 0;
191656a1485bSTali Perry }
191756a1485bSTali Perry
191856a1485bSTali Perry /* EOB: a master End Of Busy (meaning STOP completed) */
191956a1485bSTali Perry if ((FIELD_GET(NPCM_I2CCTL1_EOBINTE,
192056a1485bSTali Perry ioread8(bus->reg + NPCM_I2CCTL1)) == 1) &&
192156a1485bSTali Perry (FIELD_GET(NPCM_I2CCST3_EO_BUSY,
192256a1485bSTali Perry ioread8(bus->reg + NPCM_I2CCST3)))) {
192356a1485bSTali Perry npcm_i2c_irq_handle_eob(bus);
19248b56f98bSCharles Boyer #if IS_ENABLED(CONFIG_I2C_SLAVE)
19258b56f98bSCharles Boyer /* reenable slave if it was enabled */
19268b56f98bSCharles Boyer if (bus->slave)
19278b56f98bSCharles Boyer iowrite8(bus->slave->addr | NPCM_I2CADDR_SAEN,
19288b56f98bSCharles Boyer bus->reg + NPCM_I2CADDR1);
19298b56f98bSCharles Boyer #endif
193056a1485bSTali Perry return 0;
193156a1485bSTali Perry }
193256a1485bSTali Perry
193356a1485bSTali Perry /* Address sent and requested stall occurred (Master mode) */
193456a1485bSTali Perry if (FIELD_GET(NPCM_I2CST_STASTR, i2cst)) {
193556a1485bSTali Perry npcm_i2c_irq_handle_stall_after_start(bus);
193656a1485bSTali Perry ret = 0;
193756a1485bSTali Perry }
193856a1485bSTali Perry
193956a1485bSTali Perry /* SDA status is set - TX or RX, master */
194056a1485bSTali Perry if (FIELD_GET(NPCM_I2CST_SDAST, i2cst) ||
194156a1485bSTali Perry (bus->fifo_use &&
194256a1485bSTali Perry (npcm_i2c_tx_fifo_empty(bus) || npcm_i2c_rx_fifo_full(bus)))) {
194356a1485bSTali Perry npcm_i2c_irq_handle_sda(bus, i2cst);
194456a1485bSTali Perry ret = 0;
194556a1485bSTali Perry }
194656a1485bSTali Perry
194756a1485bSTali Perry return ret;
194856a1485bSTali Perry }
194956a1485bSTali Perry
195056a1485bSTali Perry /* recovery using TGCLK functionality of the module */
npcm_i2c_recovery_tgclk(struct i2c_adapter * _adap)195156a1485bSTali Perry static int npcm_i2c_recovery_tgclk(struct i2c_adapter *_adap)
195256a1485bSTali Perry {
195356a1485bSTali Perry u8 val;
195456a1485bSTali Perry u8 fif_cts;
195556a1485bSTali Perry bool done = false;
195656a1485bSTali Perry int status = -ENOTRECOVERABLE;
195756a1485bSTali Perry struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
195856a1485bSTali Perry /* Allow 3 bytes (27 toggles) to be read from the slave: */
195956a1485bSTali Perry int iter = 27;
196056a1485bSTali Perry
196156a1485bSTali Perry if ((npcm_i2c_get_SDA(_adap) == 1) && (npcm_i2c_get_SCL(_adap) == 1)) {
1962e5222d40STali Perry dev_dbg(bus->dev, "bus%d-0x%x recovery skipped, bus not stuck",
1963e5222d40STali Perry bus->num, bus->dest_addr);
196456a1485bSTali Perry npcm_i2c_reset(bus);
1965b0118105STyrone Ting bus->ber_state = false;
1966e5222d40STali Perry return 0;
196756a1485bSTali Perry }
196856a1485bSTali Perry
196956a1485bSTali Perry npcm_i2c_int_enable(bus, false);
197056a1485bSTali Perry npcm_i2c_disable(bus);
197156a1485bSTali Perry npcm_i2c_enable(bus);
197256a1485bSTali Perry iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
197356a1485bSTali Perry npcm_i2c_clear_tx_fifo(bus);
197456a1485bSTali Perry npcm_i2c_clear_rx_fifo(bus);
197556a1485bSTali Perry iowrite8(0, bus->reg + NPCM_I2CRXF_CTL);
197656a1485bSTali Perry iowrite8(0, bus->reg + NPCM_I2CTXF_CTL);
197756a1485bSTali Perry npcm_i2c_stall_after_start(bus, false);
197856a1485bSTali Perry
197956a1485bSTali Perry /* select bank 1 for FIFO regs */
198056a1485bSTali Perry npcm_i2c_select_bank(bus, I2C_BANK_1);
198156a1485bSTali Perry
198256a1485bSTali Perry /* clear FIFO and relevant status bits. */
198356a1485bSTali Perry fif_cts = ioread8(bus->reg + NPCM_I2CFIF_CTS);
198456a1485bSTali Perry fif_cts &= ~NPCM_I2CFIF_CTS_SLVRSTR;
198556a1485bSTali Perry fif_cts |= NPCM_I2CFIF_CTS_CLR_FIFO;
198656a1485bSTali Perry iowrite8(fif_cts, bus->reg + NPCM_I2CFIF_CTS);
198756a1485bSTali Perry npcm_i2c_set_fifo(bus, -1, 0);
198856a1485bSTali Perry
198956a1485bSTali Perry /* Repeat the following sequence until SDA is released */
199056a1485bSTali Perry do {
199156a1485bSTali Perry /* Issue a single SCL toggle */
199256a1485bSTali Perry iowrite8(NPCM_I2CCST_TGSCL, bus->reg + NPCM_I2CCST);
199356a1485bSTali Perry usleep_range(20, 30);
199456a1485bSTali Perry /* If SDA line is inactive (high), stop */
199556a1485bSTali Perry if (npcm_i2c_get_SDA(_adap)) {
199656a1485bSTali Perry done = true;
199756a1485bSTali Perry status = 0;
199856a1485bSTali Perry }
199956a1485bSTali Perry } while (!done && iter--);
200056a1485bSTali Perry
200156a1485bSTali Perry /* If SDA line is released: send start-addr-stop, to re-sync. */
200256a1485bSTali Perry if (npcm_i2c_get_SDA(_adap)) {
200356a1485bSTali Perry /* Send an address byte in write direction: */
200456a1485bSTali Perry npcm_i2c_wr_byte(bus, bus->dest_addr);
200556a1485bSTali Perry npcm_i2c_master_start(bus);
200656a1485bSTali Perry /* Wait until START condition is sent */
200756a1485bSTali Perry status = readx_poll_timeout(npcm_i2c_get_SCL, _adap, val, !val,
200856a1485bSTali Perry 20, 200);
200956a1485bSTali Perry /* If START condition was sent */
201056a1485bSTali Perry if (npcm_i2c_is_master(bus) > 0) {
201156a1485bSTali Perry usleep_range(20, 30);
201256a1485bSTali Perry npcm_i2c_master_stop(bus);
201356a1485bSTali Perry usleep_range(200, 500);
201456a1485bSTali Perry }
201556a1485bSTali Perry }
201656a1485bSTali Perry npcm_i2c_reset(bus);
201756a1485bSTali Perry npcm_i2c_int_enable(bus, true);
201856a1485bSTali Perry
201956a1485bSTali Perry if ((npcm_i2c_get_SDA(_adap) == 1) && (npcm_i2c_get_SCL(_adap) == 1))
202056a1485bSTali Perry status = 0;
202156a1485bSTali Perry else
202256a1485bSTali Perry status = -ENOTRECOVERABLE;
202356a1485bSTali Perry if (status) {
202456a1485bSTali Perry if (bus->rec_fail_cnt < ULLONG_MAX)
202556a1485bSTali Perry bus->rec_fail_cnt++;
202656a1485bSTali Perry } else {
202756a1485bSTali Perry if (bus->rec_succ_cnt < ULLONG_MAX)
202856a1485bSTali Perry bus->rec_succ_cnt++;
202956a1485bSTali Perry }
2030b0118105STyrone Ting bus->ber_state = false;
203156a1485bSTali Perry return status;
203256a1485bSTali Perry }
203356a1485bSTali Perry
203456a1485bSTali Perry /* recovery using bit banging functionality of the module */
npcm_i2c_recovery_init(struct i2c_adapter * _adap)203556a1485bSTali Perry static void npcm_i2c_recovery_init(struct i2c_adapter *_adap)
203656a1485bSTali Perry {
203756a1485bSTali Perry struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
203856a1485bSTali Perry struct i2c_bus_recovery_info *rinfo = &bus->rinfo;
203956a1485bSTali Perry
204056a1485bSTali Perry rinfo->recover_bus = npcm_i2c_recovery_tgclk;
204156a1485bSTali Perry
204256a1485bSTali Perry /*
204356a1485bSTali Perry * npcm i2c HW allows direct reading of SCL and SDA.
204456a1485bSTali Perry * However, it does not support setting SCL and SDA directly.
20450c47dd7dSJonathan Neuschäfer * The recovery function can toggle SCL when SDA is low (but not set)
20460c47dd7dSJonathan Neuschäfer * Getter functions used internally, and can be used externally.
204756a1485bSTali Perry */
204856a1485bSTali Perry rinfo->get_scl = npcm_i2c_get_SCL;
204956a1485bSTali Perry rinfo->get_sda = npcm_i2c_get_SDA;
205056a1485bSTali Perry _adap->bus_recovery_info = rinfo;
205156a1485bSTali Perry }
205256a1485bSTali Perry
205356a1485bSTali Perry /* SCLFRQ min/max field values */
205456a1485bSTali Perry #define SCLFRQ_MIN 10
205556a1485bSTali Perry #define SCLFRQ_MAX 511
205656a1485bSTali Perry #define clk_coef(freq, mul) DIV_ROUND_UP((freq) * (mul), 1000000)
205756a1485bSTali Perry
205856a1485bSTali Perry /*
205956a1485bSTali Perry * npcm_i2c_init_clk: init HW timing parameters.
20600c47dd7dSJonathan Neuschäfer * NPCM7XX i2c module timing parameters are dependent on module core clk (APB)
206156a1485bSTali Perry * and bus frequency.
20620c47dd7dSJonathan Neuschäfer * 100kHz bus requires tSCL = 4 * SCLFRQ * tCLK. LT and HT are symmetric.
20630c47dd7dSJonathan Neuschäfer * 400kHz bus requires asymmetric HT and LT. A different equation is recommended
206456a1485bSTali Perry * by the HW designer, given core clock range (equations in comments below).
206556a1485bSTali Perry *
206656a1485bSTali Perry */
npcm_i2c_init_clk(struct npcm_i2c * bus,u32 bus_freq_hz)206756a1485bSTali Perry static int npcm_i2c_init_clk(struct npcm_i2c *bus, u32 bus_freq_hz)
206856a1485bSTali Perry {
20696ddc9132STyrone Ting struct smb_timing_t *smb_timing;
20706ddc9132STyrone Ting u8 scl_table_cnt = 0, table_size = 0;
207156a1485bSTali Perry u8 fast_mode = 0;
207256a1485bSTali Perry
207356a1485bSTali Perry bus->bus_freq = bus_freq_hz;
207456a1485bSTali Perry
20756ddc9132STyrone Ting switch (bus_freq_hz) {
20766ddc9132STyrone Ting case I2C_MAX_STANDARD_MODE_FREQ:
20776ddc9132STyrone Ting smb_timing = smb_timing_100khz;
20786ddc9132STyrone Ting table_size = ARRAY_SIZE(smb_timing_100khz);
20796ddc9132STyrone Ting break;
20806ddc9132STyrone Ting case I2C_MAX_FAST_MODE_FREQ:
20816ddc9132STyrone Ting smb_timing = smb_timing_400khz;
20826ddc9132STyrone Ting table_size = ARRAY_SIZE(smb_timing_400khz);
208356a1485bSTali Perry fast_mode = I2CCTL3_400K_MODE;
20846ddc9132STyrone Ting break;
20856ddc9132STyrone Ting case I2C_MAX_FAST_MODE_PLUS_FREQ:
20866ddc9132STyrone Ting smb_timing = smb_timing_1000khz;
20876ddc9132STyrone Ting table_size = ARRAY_SIZE(smb_timing_1000khz);
208856a1485bSTali Perry fast_mode = I2CCTL3_400K_MODE;
20896ddc9132STyrone Ting break;
20906ddc9132STyrone Ting default:
20916ddc9132STyrone Ting return -EINVAL;
209256a1485bSTali Perry }
209356a1485bSTali Perry
20946ddc9132STyrone Ting for (scl_table_cnt = 0; scl_table_cnt < table_size; scl_table_cnt++)
20956ddc9132STyrone Ting if (bus->apb_clk >= smb_timing[scl_table_cnt].core_clk)
20966ddc9132STyrone Ting break;
20976ddc9132STyrone Ting
20986ddc9132STyrone Ting if (scl_table_cnt == table_size)
209956a1485bSTali Perry return -EINVAL;
210056a1485bSTali Perry
210156a1485bSTali Perry /* write sclfrq value. bits [6:0] are in I2CCTL2 reg */
21026ddc9132STyrone Ting iowrite8(FIELD_PREP(I2CCTL2_SCLFRQ6_0, smb_timing[scl_table_cnt].sclfrq & 0x7F),
210356a1485bSTali Perry bus->reg + NPCM_I2CCTL2);
210456a1485bSTali Perry
210556a1485bSTali Perry /* bits [8:7] are in I2CCTL3 reg */
21066ddc9132STyrone Ting iowrite8(FIELD_PREP(I2CCTL3_SCLFRQ8_7, (smb_timing[scl_table_cnt].sclfrq >> 7) & 0x3) |
21076ddc9132STyrone Ting fast_mode,
210856a1485bSTali Perry bus->reg + NPCM_I2CCTL3);
210956a1485bSTali Perry
211056a1485bSTali Perry /* Select Bank 0 to access NPCM_I2CCTL4/NPCM_I2CCTL5 */
211156a1485bSTali Perry npcm_i2c_select_bank(bus, I2C_BANK_0);
211256a1485bSTali Perry
211356a1485bSTali Perry if (bus_freq_hz >= I2C_MAX_FAST_MODE_FREQ) {
211456a1485bSTali Perry /*
211556a1485bSTali Perry * Set SCL Low/High Time:
211656a1485bSTali Perry * k1 = 2 * SCLLT7-0 -> Low Time = k1 / 2
211756a1485bSTali Perry * k2 = 2 * SCLLT7-0 -> High Time = k2 / 2
211856a1485bSTali Perry */
21196ddc9132STyrone Ting iowrite8(smb_timing[scl_table_cnt].scllt, bus->reg + NPCM_I2CSCLLT);
21206ddc9132STyrone Ting iowrite8(smb_timing[scl_table_cnt].sclht, bus->reg + NPCM_I2CSCLHT);
212156a1485bSTali Perry
21226ddc9132STyrone Ting iowrite8(smb_timing[scl_table_cnt].dbcnt, bus->reg + NPCM_I2CCTL5);
212356a1485bSTali Perry }
212456a1485bSTali Perry
21256ddc9132STyrone Ting iowrite8(smb_timing[scl_table_cnt].hldt, bus->reg + NPCM_I2CCTL4);
212656a1485bSTali Perry
212756a1485bSTali Perry /* Return to Bank 1, and stay there by default: */
212856a1485bSTali Perry npcm_i2c_select_bank(bus, I2C_BANK_1);
212956a1485bSTali Perry
213056a1485bSTali Perry return 0;
213156a1485bSTali Perry }
213256a1485bSTali Perry
npcm_i2c_init_module(struct npcm_i2c * bus,enum i2c_mode mode,u32 bus_freq_hz)213356a1485bSTali Perry static int npcm_i2c_init_module(struct npcm_i2c *bus, enum i2c_mode mode,
213456a1485bSTali Perry u32 bus_freq_hz)
213556a1485bSTali Perry {
213656a1485bSTali Perry u8 val;
213756a1485bSTali Perry int ret;
213856a1485bSTali Perry
213956a1485bSTali Perry /* Check whether module already enabled or frequency is out of bounds */
214056a1485bSTali Perry if ((bus->state != I2C_DISABLE && bus->state != I2C_IDLE) ||
214156a1485bSTali Perry bus_freq_hz < I2C_FREQ_MIN_HZ || bus_freq_hz > I2C_FREQ_MAX_HZ)
214256a1485bSTali Perry return -EINVAL;
214356a1485bSTali Perry
2144e5222d40STali Perry npcm_i2c_int_enable(bus, false);
214556a1485bSTali Perry npcm_i2c_disable(bus);
214656a1485bSTali Perry
214756a1485bSTali Perry /* Configure FIFO mode : */
214856a1485bSTali Perry if (FIELD_GET(I2C_VER_FIFO_EN, ioread8(bus->reg + I2C_VER))) {
214956a1485bSTali Perry bus->fifo_use = true;
215056a1485bSTali Perry npcm_i2c_select_bank(bus, I2C_BANK_0);
215156a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CFIF_CTL);
215256a1485bSTali Perry val |= NPCM_I2CFIF_CTL_FIFO_EN;
215356a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CFIF_CTL);
215456a1485bSTali Perry npcm_i2c_select_bank(bus, I2C_BANK_1);
215556a1485bSTali Perry } else {
215656a1485bSTali Perry bus->fifo_use = false;
215756a1485bSTali Perry }
215856a1485bSTali Perry
215956a1485bSTali Perry /* Configure I2C module clock frequency */
216056a1485bSTali Perry ret = npcm_i2c_init_clk(bus, bus_freq_hz);
216156a1485bSTali Perry if (ret) {
216256a1485bSTali Perry dev_err(bus->dev, "npcm_i2c_init_clk failed\n");
216356a1485bSTali Perry return ret;
216456a1485bSTali Perry }
216556a1485bSTali Perry
216656a1485bSTali Perry /* Enable module (before configuring CTL1) */
216756a1485bSTali Perry npcm_i2c_enable(bus);
216856a1485bSTali Perry bus->state = I2C_IDLE;
216956a1485bSTali Perry val = ioread8(bus->reg + NPCM_I2CCTL1);
217056a1485bSTali Perry val = (val | NPCM_I2CCTL1_NMINTE) & ~NPCM_I2CCTL1_RWS;
217156a1485bSTali Perry iowrite8(val, bus->reg + NPCM_I2CCTL1);
217256a1485bSTali Perry
217356a1485bSTali Perry npcm_i2c_reset(bus);
217456a1485bSTali Perry
2175ffad0a35STyrone Ting /* Check HW is OK: SDA and SCL should be high at this point. */
2176e5222d40STali Perry if ((npcm_i2c_get_SDA(&bus->adap) == 0) || (npcm_i2c_get_SCL(&bus->adap) == 0)) {
2177*38010591STali Perry dev_warn(bus->dev, " I2C%d SDA=%d SCL=%d, attempting to recover\n", bus->num,
2178*38010591STali Perry npcm_i2c_get_SDA(&bus->adap), npcm_i2c_get_SCL(&bus->adap));
2179*38010591STali Perry if (npcm_i2c_recovery_tgclk(&bus->adap)) {
2180*38010591STali Perry dev_err(bus->dev, "I2C%d init fail: SDA=%d SCL=%d\n",
2181*38010591STali Perry bus->num, npcm_i2c_get_SDA(&bus->adap),
2182e5222d40STali Perry npcm_i2c_get_SCL(&bus->adap));
2183e5222d40STali Perry return -ENXIO;
2184e5222d40STali Perry }
2185*38010591STali Perry }
2186e5222d40STali Perry
2187e5222d40STali Perry npcm_i2c_int_enable(bus, true);
218856a1485bSTali Perry return 0;
218956a1485bSTali Perry }
219056a1485bSTali Perry
__npcm_i2c_init(struct npcm_i2c * bus,struct platform_device * pdev)219156a1485bSTali Perry static int __npcm_i2c_init(struct npcm_i2c *bus, struct platform_device *pdev)
219256a1485bSTali Perry {
219356a1485bSTali Perry u32 clk_freq_hz;
219456a1485bSTali Perry int ret;
219556a1485bSTali Perry
219656a1485bSTali Perry /* Initialize the internal data structures */
219756a1485bSTali Perry bus->state = I2C_DISABLE;
219856a1485bSTali Perry bus->master_or_slave = I2C_SLAVE;
219956a1485bSTali Perry bus->int_time_stamp = 0;
2200f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
2201f5473692STali Perry bus->slave = NULL;
2202f5473692STali Perry #endif
220356a1485bSTali Perry
220456a1485bSTali Perry ret = device_property_read_u32(&pdev->dev, "clock-frequency",
220556a1485bSTali Perry &clk_freq_hz);
220656a1485bSTali Perry if (ret) {
220756a1485bSTali Perry dev_info(&pdev->dev, "Could not read clock-frequency property");
220856a1485bSTali Perry clk_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
220956a1485bSTali Perry }
221056a1485bSTali Perry
221156a1485bSTali Perry ret = npcm_i2c_init_module(bus, I2C_MASTER, clk_freq_hz);
221256a1485bSTali Perry if (ret) {
221356a1485bSTali Perry dev_err(&pdev->dev, "npcm_i2c_init_module failed\n");
221456a1485bSTali Perry return ret;
221556a1485bSTali Perry }
221656a1485bSTali Perry
221756a1485bSTali Perry return 0;
221856a1485bSTali Perry }
221956a1485bSTali Perry
npcm_i2c_bus_irq(int irq,void * dev_id)222056a1485bSTali Perry static irqreturn_t npcm_i2c_bus_irq(int irq, void *dev_id)
222156a1485bSTali Perry {
222256a1485bSTali Perry struct npcm_i2c *bus = dev_id;
222356a1485bSTali Perry
222456a1485bSTali Perry if (npcm_i2c_is_master(bus))
222556a1485bSTali Perry bus->master_or_slave = I2C_MASTER;
222656a1485bSTali Perry
222756a1485bSTali Perry if (bus->master_or_slave == I2C_MASTER) {
222856a1485bSTali Perry bus->int_time_stamp = jiffies;
222956a1485bSTali Perry if (!npcm_i2c_int_master_handler(bus))
223056a1485bSTali Perry return IRQ_HANDLED;
223156a1485bSTali Perry }
2232f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
2233f5473692STali Perry if (bus->slave) {
2234f5473692STali Perry bus->master_or_slave = I2C_SLAVE;
2235e5222d40STali Perry if (npcm_i2c_int_slave_handler(bus))
2236e5222d40STali Perry return IRQ_HANDLED;
2237f5473692STali Perry }
2238f5473692STali Perry #endif
2239ffad0a35STyrone Ting /* Clear status bits for spurious interrupts */
2240e5222d40STali Perry npcm_i2c_clear_master_status(bus);
2241e5222d40STali Perry
2242e5222d40STali Perry return IRQ_HANDLED;
224356a1485bSTali Perry }
224456a1485bSTali Perry
npcm_i2c_master_start_xmit(struct npcm_i2c * bus,u16 nwrite,u16 nread,u8 * write_data,u8 * read_data,bool use_PEC,bool use_read_block)224556a1485bSTali Perry static bool npcm_i2c_master_start_xmit(struct npcm_i2c *bus,
2246862dd4f7STyrone Ting u16 nwrite, u16 nread,
224756a1485bSTali Perry u8 *write_data, u8 *read_data,
224856a1485bSTali Perry bool use_PEC, bool use_read_block)
224956a1485bSTali Perry {
225056a1485bSTali Perry if (bus->state != I2C_IDLE) {
225156a1485bSTali Perry bus->cmd_err = -EBUSY;
225256a1485bSTali Perry return false;
225356a1485bSTali Perry }
225456a1485bSTali Perry bus->wr_buf = write_data;
225556a1485bSTali Perry bus->wr_size = nwrite;
225656a1485bSTali Perry bus->wr_ind = 0;
225756a1485bSTali Perry bus->rd_buf = read_data;
225856a1485bSTali Perry bus->rd_size = nread;
225956a1485bSTali Perry bus->rd_ind = 0;
226056a1485bSTali Perry bus->PEC_use = 0;
226156a1485bSTali Perry
226256a1485bSTali Perry /* for tx PEC is appended to buffer from i2c IF. PEC flag is ignored */
226356a1485bSTali Perry if (nread)
226456a1485bSTali Perry bus->PEC_use = use_PEC;
226556a1485bSTali Perry
226656a1485bSTali Perry bus->read_block_use = use_read_block;
226756a1485bSTali Perry if (nread && !nwrite)
226856a1485bSTali Perry bus->operation = I2C_READ_OPER;
226956a1485bSTali Perry else
227056a1485bSTali Perry bus->operation = I2C_WRITE_OPER;
227156a1485bSTali Perry if (bus->fifo_use) {
227256a1485bSTali Perry u8 i2cfif_cts;
227356a1485bSTali Perry
227456a1485bSTali Perry npcm_i2c_select_bank(bus, I2C_BANK_1);
227556a1485bSTali Perry /* clear FIFO and relevant status bits. */
227656a1485bSTali Perry i2cfif_cts = ioread8(bus->reg + NPCM_I2CFIF_CTS);
227756a1485bSTali Perry i2cfif_cts &= ~NPCM_I2CFIF_CTS_SLVRSTR;
227856a1485bSTali Perry i2cfif_cts |= NPCM_I2CFIF_CTS_CLR_FIFO;
227956a1485bSTali Perry iowrite8(i2cfif_cts, bus->reg + NPCM_I2CFIF_CTS);
228056a1485bSTali Perry }
228156a1485bSTali Perry
228256a1485bSTali Perry bus->state = I2C_IDLE;
228356a1485bSTali Perry npcm_i2c_stall_after_start(bus, true);
228456a1485bSTali Perry npcm_i2c_master_start(bus);
228556a1485bSTali Perry return true;
228656a1485bSTali Perry }
228756a1485bSTali Perry
npcm_i2c_master_xfer(struct i2c_adapter * adap,struct i2c_msg * msgs,int num)228856a1485bSTali Perry static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
228956a1485bSTali Perry int num)
229056a1485bSTali Perry {
229156a1485bSTali Perry struct npcm_i2c *bus = container_of(adap, struct npcm_i2c, adap);
229256a1485bSTali Perry struct i2c_msg *msg0, *msg1;
229356a1485bSTali Perry unsigned long time_left, flags;
229456a1485bSTali Perry u16 nwrite, nread;
229556a1485bSTali Perry u8 *write_data, *read_data;
2296288b2044STali Perry unsigned long timeout;
229756a1485bSTali Perry bool read_block = false;
229856a1485bSTali Perry bool read_PEC = false;
229956a1485bSTali Perry u8 bus_busy;
230056a1485bSTali Perry unsigned long timeout_usec;
230156a1485bSTali Perry
230256a1485bSTali Perry if (bus->state == I2C_DISABLE) {
230356a1485bSTali Perry dev_err(bus->dev, "I2C%d module is disabled", bus->num);
230456a1485bSTali Perry return -EINVAL;
230556a1485bSTali Perry }
230656a1485bSTali Perry
230756a1485bSTali Perry msg0 = &msgs[0];
230856a1485bSTali Perry if (msg0->flags & I2C_M_RD) { /* read */
230956a1485bSTali Perry nwrite = 0;
231056a1485bSTali Perry write_data = NULL;
231156a1485bSTali Perry read_data = msg0->buf;
231256a1485bSTali Perry if (msg0->flags & I2C_M_RECV_LEN) {
231356a1485bSTali Perry nread = 1;
231456a1485bSTali Perry read_block = true;
231556a1485bSTali Perry if (msg0->flags & I2C_CLIENT_PEC)
231656a1485bSTali Perry read_PEC = true;
231756a1485bSTali Perry } else {
231856a1485bSTali Perry nread = msg0->len;
231956a1485bSTali Perry }
232056a1485bSTali Perry } else { /* write */
232156a1485bSTali Perry nwrite = msg0->len;
232256a1485bSTali Perry write_data = msg0->buf;
232356a1485bSTali Perry nread = 0;
232456a1485bSTali Perry read_data = NULL;
232556a1485bSTali Perry if (num == 2) {
232656a1485bSTali Perry msg1 = &msgs[1];
232756a1485bSTali Perry read_data = msg1->buf;
232856a1485bSTali Perry if (msg1->flags & I2C_M_RECV_LEN) {
232956a1485bSTali Perry nread = 1;
233056a1485bSTali Perry read_block = true;
233156a1485bSTali Perry if (msg1->flags & I2C_CLIENT_PEC)
233256a1485bSTali Perry read_PEC = true;
233356a1485bSTali Perry } else {
233456a1485bSTali Perry nread = msg1->len;
233556a1485bSTali Perry read_block = false;
233656a1485bSTali Perry }
233756a1485bSTali Perry }
233856a1485bSTali Perry }
233956a1485bSTali Perry
234056a1485bSTali Perry if (nwrite >= 32 * 1024 || nread >= 32 * 1024) {
234156a1485bSTali Perry dev_err(bus->dev, "i2c%d buffer too big\n", bus->num);
234256a1485bSTali Perry return -EINVAL;
234356a1485bSTali Perry }
234456a1485bSTali Perry
23454a34b9bfSTyrone Ting time_left = jiffies + bus->adap.timeout / bus->adap.retries + 1;
234656a1485bSTali Perry do {
234756a1485bSTali Perry /*
234856a1485bSTali Perry * we must clear slave address immediately when the bus is not
234956a1485bSTali Perry * busy, so we spinlock it, but we don't keep the lock for the
235056a1485bSTali Perry * entire while since it is too long.
235156a1485bSTali Perry */
235256a1485bSTali Perry spin_lock_irqsave(&bus->lock, flags);
235356a1485bSTali Perry bus_busy = ioread8(bus->reg + NPCM_I2CCST) & NPCM_I2CCST_BB;
2354f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
2355f5473692STali Perry if (!bus_busy && bus->slave)
2356f5473692STali Perry iowrite8((bus->slave->addr & 0x7F),
2357f5473692STali Perry bus->reg + NPCM_I2CADDR1);
2358f5473692STali Perry #endif
235956a1485bSTali Perry spin_unlock_irqrestore(&bus->lock, flags);
236056a1485bSTali Perry
236156a1485bSTali Perry } while (time_is_after_jiffies(time_left) && bus_busy);
236256a1485bSTali Perry
2363b0118105STyrone Ting /*
2364862dd4f7STyrone Ting * Store the address early in a global position to ensure it is
2365862dd4f7STyrone Ting * accessible for a potential call to i2c_recover_bus().
2366862dd4f7STyrone Ting *
2367862dd4f7STyrone Ting * Since the transfer might be a read operation, remove the I2C_M_RD flag
2368862dd4f7STyrone Ting * from the bus->dest_addr for the i2c_recover_bus() call later.
2369862dd4f7STyrone Ting *
2370862dd4f7STyrone Ting * The i2c_recover_bus() uses the address in a write direction to recover
2371862dd4f7STyrone Ting * the i2c bus if some error condition occurs.
2372862dd4f7STyrone Ting *
2373862dd4f7STyrone Ting * Remove the I2C_M_RD flag from the address since npcm_i2c_master_start_xmit()
2374862dd4f7STyrone Ting * handles the read/write operation internally.
2375862dd4f7STyrone Ting */
2376862dd4f7STyrone Ting bus->dest_addr = i2c_8bit_addr_from_msg(msg0) & ~I2C_M_RD;
2377862dd4f7STyrone Ting
2378862dd4f7STyrone Ting /*
2379b0118105STyrone Ting * Check the BER (bus error) state, when ber_state is true, it means that the module
2380b0118105STyrone Ting * detects the bus error which is caused by some factor like that the electricity
2381b0118105STyrone Ting * noise occurs on the bus. Under this condition, the module is reset and the bus
2382b0118105STyrone Ting * gets recovered.
2383b0118105STyrone Ting *
2384b0118105STyrone Ting * While ber_state is false, the module reset and bus recovery also get done as the
2385b0118105STyrone Ting * bus is busy.
2386b0118105STyrone Ting */
2387b0118105STyrone Ting if (bus_busy || bus->ber_state) {
238856a1485bSTali Perry iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
238956a1485bSTali Perry npcm_i2c_reset(bus);
239056a1485bSTali Perry i2c_recover_bus(adap);
239156a1485bSTali Perry return -EAGAIN;
239256a1485bSTali Perry }
239356a1485bSTali Perry
239456a1485bSTali Perry npcm_i2c_init_params(bus);
239556a1485bSTali Perry bus->msgs = msgs;
239656a1485bSTali Perry bus->msgs_num = num;
239756a1485bSTali Perry bus->cmd_err = 0;
239856a1485bSTali Perry bus->read_block_use = read_block;
239956a1485bSTali Perry
240056a1485bSTali Perry reinit_completion(&bus->cmd_complete);
240156a1485bSTali Perry
2402e5222d40STali Perry npcm_i2c_int_enable(bus, true);
2403e5222d40STali Perry
2404862dd4f7STyrone Ting if (npcm_i2c_master_start_xmit(bus, nwrite, nread,
2405e5222d40STali Perry write_data, read_data, read_PEC,
2406e5222d40STali Perry read_block)) {
24074a34b9bfSTyrone Ting /*
24084a34b9bfSTyrone Ting * Adaptive TimeOut: estimated time in usec + 100% margin:
24094a34b9bfSTyrone Ting * 2: double the timeout for clock stretching case
24104a34b9bfSTyrone Ting * 9: bits per transaction (including the ack/nack)
24114a34b9bfSTyrone Ting */
24124a34b9bfSTyrone Ting timeout_usec = (2 * 9 * USEC_PER_SEC / bus->bus_freq) * (2 + nread + nwrite);
24134a34b9bfSTyrone Ting timeout = max_t(unsigned long, bus->adap.timeout / bus->adap.retries,
24144a34b9bfSTyrone Ting usecs_to_jiffies(timeout_usec));
241556a1485bSTali Perry time_left = wait_for_completion_timeout(&bus->cmd_complete,
241656a1485bSTali Perry timeout);
241756a1485bSTali Perry
241856a1485bSTali Perry if (time_left == 0) {
241956a1485bSTali Perry if (bus->timeout_cnt < ULLONG_MAX)
242056a1485bSTali Perry bus->timeout_cnt++;
242156a1485bSTali Perry if (bus->master_or_slave == I2C_MASTER) {
242256a1485bSTali Perry i2c_recover_bus(adap);
242356a1485bSTali Perry bus->cmd_err = -EIO;
242456a1485bSTali Perry bus->state = I2C_IDLE;
242556a1485bSTali Perry }
242656a1485bSTali Perry }
242756a1485bSTali Perry }
242856a1485bSTali Perry
242956a1485bSTali Perry /* if there was BER, check if need to recover the bus: */
243056a1485bSTali Perry if (bus->cmd_err == -EAGAIN)
2431e5222d40STali Perry bus->cmd_err = i2c_recover_bus(adap);
243256a1485bSTali Perry
24338947efc0STali Perry /*
24348947efc0STali Perry * After any type of error, check if LAST bit is still set,
24358947efc0STali Perry * due to a HW issue.
24368947efc0STali Perry * It cannot be cleared without resetting the module.
24378947efc0STali Perry */
2438e5222d40STali Perry else if (bus->cmd_err &&
2439bbc38ed5STyrone Ting (bus->data->rxf_ctl_last_pec & ioread8(bus->reg + NPCM_I2CRXF_CTL)))
24408947efc0STali Perry npcm_i2c_reset(bus);
24418947efc0STali Perry
2442ffad0a35STyrone Ting /* After any xfer, successful or not, stall and EOB must be disabled */
2443e5222d40STali Perry npcm_i2c_stall_after_start(bus, false);
2444e5222d40STali Perry npcm_i2c_eob_int(bus, false);
2445e5222d40STali Perry
2446f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
2447f5473692STali Perry /* reenable slave if it was enabled */
2448f5473692STali Perry if (bus->slave)
2449f5473692STali Perry iowrite8((bus->slave->addr & 0x7F) | NPCM_I2CADDR_SAEN,
2450f5473692STali Perry bus->reg + NPCM_I2CADDR1);
2451e5222d40STali Perry #else
2452e5222d40STali Perry npcm_i2c_int_enable(bus, false);
2453f5473692STali Perry #endif
245456a1485bSTali Perry return bus->cmd_err;
245556a1485bSTali Perry }
245656a1485bSTali Perry
npcm_i2c_functionality(struct i2c_adapter * adap)245756a1485bSTali Perry static u32 npcm_i2c_functionality(struct i2c_adapter *adap)
245856a1485bSTali Perry {
245956a1485bSTali Perry return I2C_FUNC_I2C |
246056a1485bSTali Perry I2C_FUNC_SMBUS_EMUL |
246156a1485bSTali Perry I2C_FUNC_SMBUS_BLOCK_DATA |
2462f5473692STali Perry I2C_FUNC_SMBUS_PEC |
2463f5473692STali Perry I2C_FUNC_SLAVE;
246456a1485bSTali Perry }
246556a1485bSTali Perry
246656a1485bSTali Perry static const struct i2c_adapter_quirks npcm_i2c_quirks = {
246756a1485bSTali Perry .max_read_len = 32768,
246856a1485bSTali Perry .max_write_len = 32768,
246956a1485bSTali Perry .flags = I2C_AQ_COMB_WRITE_THEN_READ,
247056a1485bSTali Perry };
247156a1485bSTali Perry
247256a1485bSTali Perry static const struct i2c_algorithm npcm_i2c_algo = {
247356a1485bSTali Perry .xfer = npcm_i2c_master_xfer,
247456a1485bSTali Perry .functionality = npcm_i2c_functionality,
2475f5473692STali Perry #if IS_ENABLED(CONFIG_I2C_SLAVE)
2476f5473692STali Perry .reg_slave = npcm_i2c_reg_slave,
2477f5473692STali Perry .unreg_slave = npcm_i2c_unreg_slave,
2478f5473692STali Perry #endif
247956a1485bSTali Perry };
248056a1485bSTali Perry
npcm_i2c_init_debugfs(struct platform_device * pdev,struct npcm_i2c * bus)248156a1485bSTali Perry static void npcm_i2c_init_debugfs(struct platform_device *pdev,
248256a1485bSTali Perry struct npcm_i2c *bus)
248356a1485bSTali Perry {
2484e19e1abcSWolfram Sang debugfs_create_u64("ber_cnt", 0444, bus->adap.debugfs, &bus->ber_cnt);
2485e19e1abcSWolfram Sang debugfs_create_u64("nack_cnt", 0444, bus->adap.debugfs, &bus->nack_cnt);
2486e19e1abcSWolfram Sang debugfs_create_u64("rec_succ_cnt", 0444, bus->adap.debugfs, &bus->rec_succ_cnt);
2487e19e1abcSWolfram Sang debugfs_create_u64("rec_fail_cnt", 0444, bus->adap.debugfs, &bus->rec_fail_cnt);
2488e19e1abcSWolfram Sang debugfs_create_u64("timeout_cnt", 0444, bus->adap.debugfs, &bus->timeout_cnt);
2489e19e1abcSWolfram Sang debugfs_create_u64("tx_complete_cnt", 0444, bus->adap.debugfs, &bus->tx_complete_cnt);
249056a1485bSTali Perry }
249156a1485bSTali Perry
npcm_i2c_probe_bus(struct platform_device * pdev)249256a1485bSTali Perry static int npcm_i2c_probe_bus(struct platform_device *pdev)
249356a1485bSTali Perry {
24940585c1d2STali Perry struct device_node *np = pdev->dev.of_node;
249556a1485bSTali Perry static struct regmap *gcr_regmap;
2496bbc38ed5STyrone Ting struct device *dev = &pdev->dev;
24970585c1d2STali Perry struct i2c_adapter *adap;
24980585c1d2STali Perry struct npcm_i2c *bus;
24990585c1d2STali Perry struct clk *i2c_clk;
250056a1485bSTali Perry int irq;
250156a1485bSTali Perry int ret;
250256a1485bSTali Perry
250356a1485bSTali Perry bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
250456a1485bSTali Perry if (!bus)
250556a1485bSTali Perry return -ENOMEM;
250656a1485bSTali Perry
250756a1485bSTali Perry bus->dev = &pdev->dev;
250856a1485bSTali Perry
2509bbc38ed5STyrone Ting bus->data = of_device_get_match_data(dev);
2510bbc38ed5STyrone Ting if (!bus->data) {
2511bbc38ed5STyrone Ting dev_err(dev, "OF data missing\n");
2512bbc38ed5STyrone Ting return -EINVAL;
2513bbc38ed5STyrone Ting }
2514bbc38ed5STyrone Ting
251556a1485bSTali Perry bus->num = of_alias_get_id(pdev->dev.of_node, "i2c");
251656a1485bSTali Perry /* core clk must be acquired to calculate module timing settings */
251756a1485bSTali Perry i2c_clk = devm_clk_get(&pdev->dev, NULL);
251856a1485bSTali Perry if (IS_ERR(i2c_clk))
251956a1485bSTali Perry return PTR_ERR(i2c_clk);
252056a1485bSTali Perry bus->apb_clk = clk_get_rate(i2c_clk);
252156a1485bSTali Perry
25220585c1d2STali Perry gcr_regmap = syscon_regmap_lookup_by_phandle(np, "nuvoton,sys-mgr");
25230585c1d2STali Perry if (IS_ERR(gcr_regmap))
252456a1485bSTali Perry gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
25250585c1d2STali Perry
252656a1485bSTali Perry if (IS_ERR(gcr_regmap))
2527de9be772SDan Carpenter return PTR_ERR(gcr_regmap);
2528bbc38ed5STyrone Ting regmap_write(gcr_regmap, NPCM_I2CSEGCTL, bus->data->segctl_init_val);
252956a1485bSTali Perry
253056a1485bSTali Perry bus->reg = devm_platform_ioremap_resource(pdev, 0);
253156a1485bSTali Perry if (IS_ERR(bus->reg))
25322667a681SGustavo A. R. Silva return PTR_ERR(bus->reg);
253356a1485bSTali Perry
253456a1485bSTali Perry spin_lock_init(&bus->lock);
253556a1485bSTali Perry init_completion(&bus->cmd_complete);
253656a1485bSTali Perry
253756a1485bSTali Perry adap = &bus->adap;
253856a1485bSTali Perry adap->owner = THIS_MODULE;
253956a1485bSTali Perry adap->retries = 3;
25404a34b9bfSTyrone Ting /*
25414a34b9bfSTyrone Ting * The users want to connect a lot of masters on the same bus.
25424a34b9bfSTyrone Ting * This timeout is used to determine the time it takes to take bus ownership.
25434a34b9bfSTyrone Ting * The transactions are very long, so waiting 35ms is not enough.
25444a34b9bfSTyrone Ting */
25454a34b9bfSTyrone Ting adap->timeout = 2 * HZ;
254656a1485bSTali Perry adap->algo = &npcm_i2c_algo;
254756a1485bSTali Perry adap->quirks = &npcm_i2c_quirks;
254856a1485bSTali Perry adap->algo_data = bus;
254956a1485bSTali Perry adap->dev.parent = &pdev->dev;
255056a1485bSTali Perry adap->dev.of_node = pdev->dev.of_node;
255156a1485bSTali Perry adap->nr = pdev->id;
255256a1485bSTali Perry
255356a1485bSTali Perry irq = platform_get_irq(pdev, 0);
255456a1485bSTali Perry if (irq < 0)
255556a1485bSTali Perry return irq;
255656a1485bSTali Perry
2557dd1998e2STyrone Ting /*
2558dd1998e2STyrone Ting * Disable the interrupt to avoid the interrupt handler being triggered
2559dd1998e2STyrone Ting * incorrectly by the asynchronous interrupt status since the machine
2560dd1998e2STyrone Ting * might do a warm reset during the last smbus/i2c transfer session.
2561dd1998e2STyrone Ting */
2562dd1998e2STyrone Ting npcm_i2c_int_enable(bus, false);
2563dd1998e2STyrone Ting
256456a1485bSTali Perry ret = devm_request_irq(bus->dev, irq, npcm_i2c_bus_irq, 0,
256556a1485bSTali Perry dev_name(bus->dev), bus);
256656a1485bSTali Perry if (ret)
256756a1485bSTali Perry return ret;
256856a1485bSTali Perry
256956a1485bSTali Perry ret = __npcm_i2c_init(bus, pdev);
257056a1485bSTali Perry if (ret)
257156a1485bSTali Perry return ret;
257256a1485bSTali Perry
257356a1485bSTali Perry npcm_i2c_recovery_init(adap);
257456a1485bSTali Perry
257556a1485bSTali Perry i2c_set_adapdata(adap, bus);
257656a1485bSTali Perry
257756a1485bSTali Perry snprintf(bus->adap.name, sizeof(bus->adap.name), "npcm_i2c_%d",
257856a1485bSTali Perry bus->num);
257956a1485bSTali Perry ret = i2c_add_numbered_adapter(&bus->adap);
258056a1485bSTali Perry if (ret)
258156a1485bSTali Perry return ret;
258256a1485bSTali Perry
258356a1485bSTali Perry platform_set_drvdata(pdev, bus);
258456a1485bSTali Perry npcm_i2c_init_debugfs(pdev, bus);
258556a1485bSTali Perry return 0;
258656a1485bSTali Perry }
258756a1485bSTali Perry
npcm_i2c_remove_bus(struct platform_device * pdev)2588e190a0c3SUwe Kleine-König static void npcm_i2c_remove_bus(struct platform_device *pdev)
258956a1485bSTali Perry {
259056a1485bSTali Perry unsigned long lock_flags;
259156a1485bSTali Perry struct npcm_i2c *bus = platform_get_drvdata(pdev);
259256a1485bSTali Perry
259356a1485bSTali Perry spin_lock_irqsave(&bus->lock, lock_flags);
259456a1485bSTali Perry npcm_i2c_disable(bus);
259556a1485bSTali Perry spin_unlock_irqrestore(&bus->lock, lock_flags);
259656a1485bSTali Perry i2c_del_adapter(&bus->adap);
259756a1485bSTali Perry }
259856a1485bSTali Perry
259956a1485bSTali Perry static const struct of_device_id npcm_i2c_bus_of_table[] = {
2600bbc38ed5STyrone Ting { .compatible = "nuvoton,npcm750-i2c", .data = &npxm7xx_i2c_data },
2601bbc38ed5STyrone Ting { .compatible = "nuvoton,npcm845-i2c", .data = &npxm8xx_i2c_data },
260256a1485bSTali Perry {}
260356a1485bSTali Perry };
260456a1485bSTali Perry MODULE_DEVICE_TABLE(of, npcm_i2c_bus_of_table);
260556a1485bSTali Perry
260656a1485bSTali Perry static struct platform_driver npcm_i2c_bus_driver = {
260756a1485bSTali Perry .probe = npcm_i2c_probe_bus,
260832a0a94aSUwe Kleine-König .remove = npcm_i2c_remove_bus,
260956a1485bSTali Perry .driver = {
261056a1485bSTali Perry .name = "nuvoton-i2c",
261156a1485bSTali Perry .of_match_table = npcm_i2c_bus_of_table,
261256a1485bSTali Perry }
261356a1485bSTali Perry };
261456a1485bSTali Perry
2615e19e1abcSWolfram Sang module_platform_driver(npcm_i2c_bus_driver);
261656a1485bSTali Perry
261756a1485bSTali Perry MODULE_AUTHOR("Avi Fishman <avi.fishman@gmail.com>");
261856a1485bSTali Perry MODULE_AUTHOR("Tali Perry <tali.perry@nuvoton.com>");
261956a1485bSTali Perry MODULE_AUTHOR("Tyrone Ting <kfting@nuvoton.com>");
262056a1485bSTali Perry MODULE_DESCRIPTION("Nuvoton I2C Bus Driver");
262156a1485bSTali Perry MODULE_LICENSE("GPL v2");
2622