Skip to content

Commit aef79e1

Browse files
NXP-CarlosSongalexandrebelloni
authored andcommitted
i3c: master: support to adjust first broadcast address speed
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 <[email protected]> Reviewed-by: Miquel Raynal <[email protected]> Reviewed-by: Frank Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent 061dd21 commit aef79e1

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

drivers/i3c/master.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,6 +1868,12 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
18681868
goto err_bus_cleanup;
18691869
}
18701870

1871+
if (master->ops->set_speed) {
1872+
ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_SLOW_SPEED);
1873+
if (ret)
1874+
goto err_bus_cleanup;
1875+
}
1876+
18711877
/*
18721878
* Reset all dynamic address that may have been assigned before
18731879
* (assigned by the bootloader for example).
@@ -1876,6 +1882,12 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
18761882
if (ret && ret != I3C_ERROR_M2)
18771883
goto err_bus_cleanup;
18781884

1885+
if (master->ops->set_speed) {
1886+
master->ops->set_speed(master, I3C_OPEN_DRAIN_NORMAL_SPEED);
1887+
if (ret)
1888+
goto err_bus_cleanup;
1889+
}
1890+
18791891
/* Disable all slave events before starting DAA. */
18801892
ret = i3c_master_disec_locked(master, I3C_BROADCAST_ADDR,
18811893
I3C_CCC_EVENT_SIR | I3C_CCC_EVENT_MR |

include/linux/i3c/master.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,20 @@ enum i3c_bus_mode {
277277
I3C_BUS_MODE_MIXED_SLOW,
278278
};
279279

280+
/**
281+
* enum i3c_open_drain_speed - I3C open-drain speed
282+
* @I3C_OPEN_DRAIN_SLOW_SPEED: Slow open-drain speed for sending the first
283+
* broadcast address. The first broadcast address at this speed
284+
* will be visible to all devices on the I3C bus. I3C devices
285+
* working in I2C mode will turn off their spike filter when
286+
* switching into I3C mode.
287+
* @I3C_OPEN_DRAIN_NORMAL_SPEED: Normal open-drain speed in I3C bus mode.
288+
*/
289+
enum i3c_open_drain_speed {
290+
I3C_OPEN_DRAIN_SLOW_SPEED,
291+
I3C_OPEN_DRAIN_NORMAL_SPEED,
292+
};
293+
280294
/**
281295
* enum i3c_addr_slot_status - I3C address slot status
282296
* @I3C_ADDR_SLOT_FREE: address is free
@@ -436,6 +450,7 @@ struct i3c_bus {
436450
* NULL.
437451
* @enable_hotjoin: enable hot join event detect.
438452
* @disable_hotjoin: disable hot join event detect.
453+
* @set_speed: adjust I3C open drain mode timing.
439454
*/
440455
struct i3c_master_controller_ops {
441456
int (*bus_init)(struct i3c_master_controller *master);
@@ -464,6 +479,7 @@ struct i3c_master_controller_ops {
464479
struct i3c_ibi_slot *slot);
465480
int (*enable_hotjoin)(struct i3c_master_controller *master);
466481
int (*disable_hotjoin)(struct i3c_master_controller *master);
482+
int (*set_speed)(struct i3c_master_controller *master, enum i3c_open_drain_speed speed);
467483
};
468484

469485
/**

0 commit comments

Comments
 (0)