@@ -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);
@@ -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);
@@ -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;