Skip to content

Commit

Permalink
i3c: master: support to adjust first broadcast address speed
Browse files Browse the repository at this point in the history
According to I3C spec 6.2 Timing Specification, the Open Drain High Period
of SCL Clock timing for first broadcast address should be adjusted to 200ns
at least. I3C device working as i2c device will see the broadcast to close
its Spike Filter then change to work at I3C mode. After that I3C open drain
SCL high level should be adjusted back.

Signed-off-by: Carlos Song <carlos.song@nxp.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20240910051626.4052552-1-carlos.song@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
  • Loading branch information
Carlos Song authored and Alexandre Belloni committed Sep 17, 2024
1 parent 061dd21 commit aef79e1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
12 changes: 12 additions & 0 deletions drivers/i3c/master.c
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -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 |
Expand Down
16 changes: 16 additions & 0 deletions include/linux/i3c/master.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 sending the first
* broadcast address. The first broadcast address at this speed
* will be visible to all devices on the I3C bus. I3C devices
* working in I2C mode will turn off their spike filter when
* switching into I3C mode.
* @I3C_OPEN_DRAIN_NORMAL_SPEED: Normal open-drain speed in 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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
};

/**
Expand Down

0 comments on commit aef79e1

Please sign in to comment.