@@ -1868,6 +1868,12 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
goto err_bus_cleanup;
}
+ if (master->ops->set_speed) {
+ ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_SLOW_SPEED);
+ if (ret)
+ goto err_bus_cleanup;
+ }
+
/*
* Reset all dynamic address that may have been assigned before
* (assigned by the bootloader for example).
@@ -1876,6 +1882,12 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
if (ret && ret != I3C_ERROR_M2)
goto err_bus_cleanup;
+ if (master->ops->set_speed) {
+ master->ops->set_speed(master, I3C_OPEN_DRAIN_NORMAL_SPEED);
+ if (ret)
+ goto err_bus_cleanup;
+ }
+
/* Disable all slave events before starting DAA. */
ret = i3c_master_disec_locked(master, I3C_BROADCAST_ADDR,
I3C_CCC_EVENT_SIR | I3C_CCC_EVENT_MR |
@@ -277,6 +277,20 @@ enum i3c_bus_mode {
I3C_BUS_MODE_MIXED_SLOW,
};
+/**
+ * enum i3c_open_drain_speed - I3C open drain speed
+ * @I3C_OPEN_DRAIN_SLOW_SPEED: Slow open drain speed for First Broadcast Address.
+ * First Broadcast Address in this speed is visible to all I2C/I3C
+ * devices on the I3C bus. I3C device working as a I2C device will
+ * turn off its 50ns Spike Filter to change to work in I3C mode.
+ * @I3C_OPEN_DRAIN_NORMAL_SPEED: Normal open drain speed configured according to
+ * I3C bus mode.
+ */
+enum i3c_open_drain_speed {
+ I3C_OPEN_DRAIN_SLOW_SPEED,
+ I3C_OPEN_DRAIN_NORMAL_SPEED,
+};
+
/**
* enum i3c_addr_slot_status - I3C address slot status
* @I3C_ADDR_SLOT_FREE: address is free
@@ -436,6 +450,7 @@ struct i3c_bus {
* NULL.
* @enable_hotjoin: enable hot join event detect.
* @disable_hotjoin: disable hot join event detect.
+ * @set_speed: adjust I3C open drain mode timing.
*/
struct i3c_master_controller_ops {
int (*bus_init)(struct i3c_master_controller *master);
@@ -464,6 +479,7 @@ struct i3c_master_controller_ops {
struct i3c_ibi_slot *slot);
int (*enable_hotjoin)(struct i3c_master_controller *master);
int (*disable_hotjoin)(struct i3c_master_controller *master);
+ int (*set_speed)(struct i3c_master_controller *master, enum i3c_open_drain_speed speed);
};
/**