i2c: designware_i2c: Check if the device is powered
authorRaul E Rangel <rrangel@chromium.org>
Wed, 22 Apr 2020 16:13:54 +0000 (10:13 -0600)
committerHeiko Schocher <hs@denx.de>
Thu, 28 May 2020 03:50:47 +0000 (05:50 +0200)
If the device doesn't return a version that means the device is
non-functional.

The dw_i2c_regs had invalid offsets for the version field. I got the
correct value from the DesignWare databook. It also matches what the
Picasso PPR says.

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Tested on chromebook_coral:
Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/i2c/designware_i2c.c

index c6a20721f68cb5b286c6d9ffd8e333db23b2e096..3616e2105fab36e2689cefb9ae8871fb44cd9835 100644 (file)
 #include <dm/device_compat.h>
 #include <linux/err.h>
 
+/*
+ * This assigned unique hex value is constant and is derived from the two ASCII
+ * letters 'DW' followed by a 16-bit unsigned number
+ */
+#define DW_I2C_COMP_TYPE       0x44570140
+
 #ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED
 static int  dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
 {
@@ -766,6 +772,17 @@ int designware_i2c_ofdata_to_platdata(struct udevice *bus)
 int designware_i2c_probe(struct udevice *bus)
 {
        struct dw_i2c *priv = dev_get_priv(bus);
+       uint comp_type;
+
+       comp_type = readl(&priv->regs->comp_type);
+       if (comp_type != DW_I2C_COMP_TYPE) {
+               log_err("I2C bus %s has unknown type %#x\n", bus->name,
+                       comp_type);
+               return -ENXIO;
+       }
+
+       log_info("I2C bus %s version %#x\n", bus->name,
+                readl(&priv->regs->comp_version));
 
        return __dw_i2c_init(priv->regs, 0, 0);
 }