blob: e4ab68690632c76944cce89bc61c1e51389c05a0 [file] [log] [blame]
From 2ea5690976bd9380aa98066121a81def7b12069c Mon Sep 17 00:00:00 2001
From: "William A. Kennington III" <wak@google.com>
Date: Wed, 25 Sep 2024 14:02:27 -0700
Subject: [PATCH] i2c: npcm: Sync with 6.1
Upstream(nuvoton/NPCM-6.1-OpenBMC): 7617e2d374be849fa2dd63969e464c3fd669ec0c
Signed-off-by: William A. Kennington III <wak@google.com>
---
drivers/i2c/busses/i2c-npcm7xx.c | 120 +++++++++++++++++--------------
1 file changed, 66 insertions(+), 54 deletions(-)
diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c
index bfef6ae45988..bbc2cf7ef2d4 100644
--- a/drivers/i2c/busses/i2c-npcm7xx.c
+++ b/drivers/i2c/busses/i2c-npcm7xx.c
@@ -1,9 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
+// nuvoton/NPCM-6.1-OpenBMC: 7617e2d374be849fa2dd63969e464c3fd669ec0c
/*
* Nuvoton NPCM7xx I2C Controller driver
*
* Copyright (C) 2020 Nuvoton Technologies tali.perry@nuvoton.com
*/
+#include <linux/version.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
@@ -106,7 +108,7 @@ enum i2c_addr {
#define NPCM_I2CCST3 0x19
#define I2C_VER 0x1F
-/*BANK0 regs*/
+/* BANK 0 regs */
#define NPCM_I2CADDR3 0x10
#define NPCM_I2CADDR7 0x11
#define NPCM_I2CADDR4 0x12
@@ -115,6 +117,20 @@ enum i2c_addr {
#define NPCM_I2CADDR9 0x15
#define NPCM_I2CADDR6 0x16
#define NPCM_I2CADDR10 0x17
+#define NPCM_I2CCTL4 0x1A
+#define NPCM_I2CCTL5 0x1B
+#define NPCM_I2CSCLLT 0x1C /* SCL Low Time */
+#define NPCM_I2CFIF_CTL 0x1D /* FIFO Control */
+#define NPCM_I2CSCLHT 0x1E /* SCL High Time */
+
+/* BANK 1 regs */
+#define NPCM_I2CFIF_CTS 0x10 /* Both FIFOs Control and Status */
+#define NPCM_I2CTXF_CTL 0x12 /* Tx-FIFO Control */
+#define NPCM_I2CT_OUT 0x14 /* Bus T.O. */
+#define NPCM_I2CPEC 0x16 /* PEC Data */
+#define NPCM_I2CTXF_STS 0x1A /* Tx-FIFO Status */
+#define NPCM_I2CRXF_STS 0x1C /* Rx-FIFO Status */
+#define NPCM_I2CRXF_CTL 0x1E /* Rx-FIFO Control */
#if IS_ENABLED(CONFIG_I2C_SLAVE)
/*
@@ -131,66 +147,51 @@ static const int npcm_i2caddr[I2C_NUM_OWN_ADDR] = {
};
#endif
-#define NPCM_I2CCTL4 0x1A
-#define NPCM_I2CCTL5 0x1B
-#define NPCM_I2CSCLLT 0x1C /* SCL Low Time */
-#define NPCM_I2CFIF_CTL 0x1D /* FIFO Control */
-#define NPCM_I2CSCLHT 0x1E /* SCL High Time */
-
-/* BANK 1 regs */
-#define NPCM_I2CFIF_CTS 0x10 /* Both FIFOs Control and Status */
-#define NPCM_I2CTXF_CTL 0x12 /* Tx-FIFO Control */
-#define NPCM_I2CT_OUT 0x14 /* Bus T.O. */
-#define NPCM_I2CPEC 0x16 /* PEC Data */
-#define NPCM_I2CTXF_STS 0x1A /* Tx-FIFO Status */
-#define NPCM_I2CRXF_STS 0x1C /* Rx-FIFO Status */
-#define NPCM_I2CRXF_CTL 0x1E /* Rx-FIFO Control */
-
/* NPCM_I2CST reg fields */
-#define NPCM_I2CST_XMIT BIT(0)
-#define NPCM_I2CST_MASTER BIT(1)
-#define NPCM_I2CST_NMATCH BIT(2)
-#define NPCM_I2CST_STASTR BIT(3)
-#define NPCM_I2CST_NEGACK BIT(4)
-#define NPCM_I2CST_BER BIT(5)
-#define NPCM_I2CST_SDAST BIT(6)
-#define NPCM_I2CST_SLVSTP BIT(7)
+#define NPCM_I2CST_XMIT BIT(0) /* Transmit mode */
+#define NPCM_I2CST_MASTER BIT(1) /* Master mode */
+#define NPCM_I2CST_NMATCH BIT(2) /* New match */
+#define NPCM_I2CST_STASTR BIT(3) /* Stall after start */
+#define NPCM_I2CST_NEGACK BIT(4) /* Negative ACK */
+#define NPCM_I2CST_BER BIT(5) /* Bus error */
+#define NPCM_I2CST_SDAST BIT(6) /* SDA status */
+#define NPCM_I2CST_SLVSTP BIT(7) /* Slave stop */
/* NPCM_I2CCST reg fields */
-#define NPCM_I2CCST_BUSY BIT(0)
-#define NPCM_I2CCST_BB BIT(1)
-#define NPCM_I2CCST_MATCH BIT(2)
-#define NPCM_I2CCST_GCMATCH BIT(3)
-#define NPCM_I2CCST_TSDA BIT(4)
-#define NPCM_I2CCST_TGSCL BIT(5)
-#define NPCM_I2CCST_MATCHAF BIT(6)
-#define NPCM_I2CCST_ARPMATCH BIT(7)
+#define NPCM_I2CCST_BUSY BIT(0) /* Busy */
+#define NPCM_I2CCST_BB BIT(1) /* Bus busy */
+#define NPCM_I2CCST_MATCH BIT(2) /* Address match */
+#define NPCM_I2CCST_GCMATCH BIT(3) /* Global call match */
+#define NPCM_I2CCST_TSDA BIT(4) /* Test SDA line */
+#define NPCM_I2CCST_TGSCL BIT(5) /* Toggle SCL line */
+#define NPCM_I2CCST_MATCHAF BIT(6) /* Match address field */
+#define NPCM_I2CCST_ARPMATCH BIT(7) /* ARP address match */
/* NPCM_I2CCTL1 reg fields */
-#define NPCM_I2CCTL1_START BIT(0)
-#define NPCM_I2CCTL1_STOP BIT(1)
-#define NPCM_I2CCTL1_INTEN BIT(2)
+#define NPCM_I2CCTL1_START BIT(0) /* Generate start condition */
+#define NPCM_I2CCTL1_STOP BIT(1) /* Generate stop condition */
+#define NPCM_I2CCTL1_INTEN BIT(2) /* Interrupt enable */
#define NPCM_I2CCTL1_EOBINTE BIT(3)
#define NPCM_I2CCTL1_ACK BIT(4)
-#define NPCM_I2CCTL1_GCMEN BIT(5)
-#define NPCM_I2CCTL1_NMINTE BIT(6)
-#define NPCM_I2CCTL1_STASTRE BIT(7)
+#define NPCM_I2CCTL1_GCMEN BIT(5) /* Global call match enable */
+#define NPCM_I2CCTL1_NMINTE BIT(6) /* New match interrupt enable */
+#define NPCM_I2CCTL1_STASTRE BIT(7) /* Stall after start enable */
/* RW1S fields (inside a RW reg): */
#define NPCM_I2CCTL1_RWS \
(NPCM_I2CCTL1_START | NPCM_I2CCTL1_STOP | NPCM_I2CCTL1_ACK)
/* npcm_i2caddr reg fields */
-#define NPCM_I2CADDR_A GENMASK(6, 0)
-#define NPCM_I2CADDR_SAEN BIT(7)
+#define NPCM_I2CADDR_A GENMASK(6, 0) /* Address */
+#define NPCM_I2CADDR_SAEN BIT(7) /* Slave address enable */
/* NPCM_I2CCTL2 reg fields */
-#define I2CCTL2_ENABLE BIT(0)
-#define I2CCTL2_SCLFRQ6_0 GENMASK(7, 1)
+#define I2CCTL2_ENABLE BIT(0) /* Module enable */
+#define I2CCTL2_SCLFRQ6_0 GENMASK(7, 1) /* Bits 0:6 of frequency divisor */
/* NPCM_I2CCTL3 reg fields */
-#define I2CCTL3_SCLFRQ8_7 GENMASK(1, 0)
-#define I2CCTL3_ARPMEN BIT(2)
+#define I2CCTL3_SCLFRQ8_7 GENMASK(1, 0) /* Bits 7:8 of frequency divisor */
+#define I2CCTL3_ARPMEN BIT(2) /* ARP match enable */
#define I2CCTL3_IDL_START BIT(3)
#define I2CCTL3_400K_MODE BIT(4)
#define I2CCTL3_BNK_SEL BIT(5)
@@ -1785,6 +1786,12 @@ static int npcm_i2c_int_master_handler(struct npcm_i2c *bus)
(FIELD_GET(NPCM_I2CCST3_EO_BUSY,
ioread8(bus->reg + NPCM_I2CCST3)))) {
npcm_i2c_irq_handle_eob(bus);
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ /* reenable slave if it was enabled */
+ if (bus->slave)
+ iowrite8((bus->slave->addr & 0x7F) | NPCM_I2CADDR_SAEN,
+ bus->reg + NPCM_I2CADDR1);
+#endif
return 0;
}
@@ -2433,6 +2440,8 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev)
if (irq < 0)
return irq;
+ npcm_i2c_int_enable(bus, false);
+
ret = devm_request_irq(bus->dev, irq, npcm_i2c_bus_irq, 0,
dev_name(bus->dev), bus);
if (ret)
@@ -2457,7 +2466,11 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev)
return 0;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,11,0)
static int npcm_i2c_remove_bus(struct platform_device *pdev)
+#else
+static void npcm_i2c_remove_bus(struct platform_device *pdev)
+#endif
{
unsigned long lock_flags;
struct npcm_i2c *bus = platform_get_drvdata(pdev);
@@ -2467,7 +2480,9 @@ static int npcm_i2c_remove_bus(struct platform_device *pdev)
npcm_i2c_disable(bus);
spin_unlock_irqrestore(&bus->lock, lock_flags);
i2c_del_adapter(&bus->adap);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,11,0)
return 0;
+#endif
}
static const struct of_device_id npcm_i2c_bus_of_table[] = {
--
2.46.0.792.g87dc391469-goog