Hello Coben,

On 30.05.26 17:24, Coben Han wrote:
Probing i2c slave device just needs its device address.

A certain type of chipsets such as RTC S35390A have no offset,
which means address length should be 0.

But the current designware_i2c_probe_chip function requires
offset 0 and its length 1.

This causes the designware-i2c to be initialized again and again.

Furthermore, after booting into kernel, the designware-i2c kernel
driver complains its controller timeout.

This patch fixes this misbehaviour in such way that  only device
address is issued, no reinitialization needs when target device
not detected, the designware-i2c kernel driver continues working.

Signed-off-by: Coben Han <[email protected]>
---
  drivers/i2c/designware_i2c.c | 52 +++++++++++++++++++++++++++++-------
  1 file changed, 42 insertions(+), 10 deletions(-)

Sounds valid to me, it would be good to have some Tested by tags
from other users, that this change does not break.


diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 8ad716f410e..a7d3b609aca 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -672,18 +672,50 @@ static int dw_i2c_write(struct i2c_adapter *adap, u8 dev, 
uint addr,
  }
/* dw_i2c_probe - Probe the i2c chip */
-static int dw_i2c_probe(struct i2c_adapter *adap, u8 dev)
+static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr, uint 
chip_flags)
  {
-       struct i2c_regs *i2c_base = i2c_get_base(adap);
-       u32 tmp;
-       int ret;
+       struct dw_i2c *i2c = dev_get_priv(bus);
+       struct i2c_regs *i2c_base = i2c->regs;
+       u32 start_time, ic_status;
+       int ret = 0;
- /*
-        * Try to read the first location of the chip.
-        */
-       ret = __dw_i2c_read(i2c_base, dev, 0, 1, (uchar *)&tmp, 1);
-       if (ret)
-               dw_i2c_init(adap, adap->speed, adap->slaveaddr);
+       if (i2c_wait_for_bb(i2c_base) < 0)
+               return 1;

Why not returning -ETIMEDOUT ? (or better the return code from i2c_wait_for_bb()
which -ETIMEDOUT, but may in future it changes...

+
+       dw_i2c_enable(i2c_base, false);
+       writel(chip_addr, &i2c_base->ic_tar);
+       dw_i2c_enable(i2c_base, true);
+
+       writel(IC_STOP, &i2c_base->ic_cmd_data);
+
+       start_time = get_timer(0);
+       while (1) {
+               ic_status = readl(&i2c_base->ic_status);
+
+               if ((ic_status & IC_STATUS_TFE) && !(ic_status & IC_STATUS_MA))
+                       break;
+
+               if (readl(&i2c_base->ic_raw_intr_stat) & IC_TX_ABRT) {
+                       readl(&i2c_base->ic_clr_tx_abrt);
+                       ret = -EREMOTEIO;
+                       break;
+               }
+
+               if (get_timer(start_time) > I2C_BYTE_TO) {
+                       ret = -ETIMEDOUT;
+                       break;
+               }
+       }
+
+       start_time = get_timer(0);
+       while (1) {
+               if ((readl(&i2c_base->ic_raw_intr_stat) & IC_STOP_DET)) {
+                       readl(&i2c_base->ic_clr_stop_det);
+                       break;
+               } else if (get_timer(start_time) > I2C_STOPDET_TO) {
+                       break;
+               }
+       }
return ret;
  }


bye,
Heiko
--
Nabla Software Engineering
HRB 40522 Augsburg
Phone: +49 821 45592596
E-Mail: [email protected]
Geschäftsführer : Stefano Babic

Reply via email to