aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorSven Peter <sven@svenpeter.dev>2021-10-08 18:35:32 +0200
committerWolfram Sang <wsa@kernel.org>2021-10-11 11:45:56 +0200
commit3abdc89b5e309c63fa631de38cbec0755e5b2ee7 (patch)
treeac06149c523e57520fffd697350d50e1f7ec8a17 /drivers/i2c
parenti2c: pasemi: Add Apple platform driver (diff)
downloadlinux-dev-3abdc89b5e309c63fa631de38cbec0755e5b2ee7.tar.xz
linux-dev-3abdc89b5e309c63fa631de38cbec0755e5b2ee7.zip
i2c: pasemi: Set enable bit for Apple variant
Some later revisions after the original PASemi I2C controller introduce what likely is an enable bit to the CTL register. Without setting it the actual i2c transmission is never started. Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Sven Peter <sven@svenpeter.dev> Acked-by: Olof Johansson <olof@lixom.net> Tested-by: Christian Zigotzky <chzigotzky@xenosoft.de> Signed-off-by: Wolfram Sang <wsa@kernel.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-pasemi-core.c8
-rw-r--r--drivers/i2c/busses/i2c-pasemi-core.h3
-rw-r--r--drivers/i2c/busses/i2c-pasemi-pci.c6
3 files changed, 17 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
index 3d87b64dd9f7..4e161a4089d8 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.c
+++ b/drivers/i2c/busses/i2c-pasemi-core.c
@@ -22,6 +22,7 @@
#define REG_MRXFIFO 0x04
#define REG_SMSTA 0x14
#define REG_CTL 0x1c
+#define REG_REV 0x28
/* Register defs */
#define MTXFIFO_READ 0x00000400
@@ -37,6 +38,7 @@
#define CTL_MRR 0x00000400
#define CTL_MTR 0x00000200
+#define CTL_EN 0x00000800
#define CTL_CLK_M 0x000000ff
static inline void reg_write(struct pasemi_smbus *smbus, int reg, int val)
@@ -60,6 +62,9 @@ static void pasemi_reset(struct pasemi_smbus *smbus)
{
u32 val = (CTL_MTR | CTL_MRR | (smbus->clk_div & CTL_CLK_M));
+ if (smbus->hw_rev >= 6)
+ val |= CTL_EN;
+
reg_write(smbus, REG_CTL, val);
}
@@ -335,6 +340,9 @@ int pasemi_i2c_common_probe(struct pasemi_smbus *smbus)
/* set up the sysfs linkage to our parent device */
smbus->adapter.dev.parent = smbus->dev;
+ if (smbus->hw_rev != PASEMI_HW_REV_PCI)
+ smbus->hw_rev = reg_read(smbus, REG_REV);
+
pasemi_reset(smbus);
error = devm_i2c_add_adapter(smbus->dev, &smbus->adapter);
diff --git a/drivers/i2c/busses/i2c-pasemi-core.h b/drivers/i2c/busses/i2c-pasemi-core.h
index aca4e2da9089..4655124a37f3 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.h
+++ b/drivers/i2c/busses/i2c-pasemi-core.h
@@ -8,11 +8,14 @@
#include <linux/io.h>
#include <linux/kernel.h>
+#define PASEMI_HW_REV_PCI -1
+
struct pasemi_smbus {
struct device *dev;
struct i2c_adapter adapter;
void __iomem *ioaddr;
unsigned int clk_div;
+ int hw_rev;
};
int pasemi_i2c_common_probe(struct pasemi_smbus *smbus);
diff --git a/drivers/i2c/busses/i2c-pasemi-pci.c b/drivers/i2c/busses/i2c-pasemi-pci.c
index 4251e7b9f177..1ab1f28744fb 100644
--- a/drivers/i2c/busses/i2c-pasemi-pci.c
+++ b/drivers/i2c/busses/i2c-pasemi-pci.c
@@ -42,6 +42,12 @@ static int pasemi_smb_pci_probe(struct pci_dev *dev,
size = pci_resource_len(dev, 0);
smbus->clk_div = CLK_100K_DIV;
+ /*
+ * The original PASemi PCI controllers don't have a register for
+ * their HW revision.
+ */
+ smbus->hw_rev = PASEMI_HW_REV_PCI;
+
if (!devm_request_region(&dev->dev, base, size,
pasemi_smb_pci_driver.name))
return -EBUSY;