Skip to content

Commit 6bdc662

Browse files
cbabroskiAndi Shyti
authored andcommitted
i2c-mlxbf: Add repeated start condition support
Add support for SMBus repeated start conditions to the Mellanox I2C driver. This support is specifically enabled for the I2C_FUNC_SMBUS_WRITE_I2C_BLOCK implementation which is required for communication with a specific I2C device on BlueField 3. Signed-off-by: Chris Babroski <cbabroski@nvidia.com> Reviewed-by: Asmaa Mnebhi <asmaa@nvidia.com> Reviewed-by: Khalil Blaiech <kblaiech@nvidia.com> Link: https://lore.kernel.org/r/20250506193059.321345-1-cbabroski@nvidia.com Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
1 parent 24d9f60 commit 6bdc662

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

drivers/i2c/busses/i2c-mlxbf.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@
224224

225225
#define MLXBF_I2C_MASTER_ENABLE \
226226
(MLXBF_I2C_MASTER_LOCK_BIT | MLXBF_I2C_MASTER_BUSY_BIT | \
227-
MLXBF_I2C_MASTER_START_BIT | MLXBF_I2C_MASTER_STOP_BIT)
227+
MLXBF_I2C_MASTER_START_BIT)
228228

229229
#define MLXBF_I2C_MASTER_ENABLE_WRITE \
230230
(MLXBF_I2C_MASTER_ENABLE | MLXBF_I2C_MASTER_CTL_WRITE_BIT)
@@ -338,6 +338,7 @@ enum {
338338
MLXBF_I2C_F_SMBUS_BLOCK = BIT(5),
339339
MLXBF_I2C_F_SMBUS_PEC = BIT(6),
340340
MLXBF_I2C_F_SMBUS_PROCESS_CALL = BIT(7),
341+
MLXBF_I2C_F_WRITE_WITHOUT_STOP = BIT(8),
341342
};
342343

343344
/* Mellanox BlueField chip type. */
@@ -638,16 +639,19 @@ static void mlxbf_i2c_smbus_read_data(struct mlxbf_i2c_priv *priv,
638639
}
639640

640641
static int mlxbf_i2c_smbus_enable(struct mlxbf_i2c_priv *priv, u8 slave,
641-
u8 len, u8 block_en, u8 pec_en, bool read)
642+
u8 len, u8 block_en, u8 pec_en, bool read,
643+
bool stop)
642644
{
643-
u32 command;
645+
u32 command = 0;
644646

645647
/* Set Master GW control word. */
648+
if (stop)
649+
command |= MLXBF_I2C_MASTER_STOP_BIT;
646650
if (read) {
647-
command = MLXBF_I2C_MASTER_ENABLE_READ;
651+
command |= MLXBF_I2C_MASTER_ENABLE_READ;
648652
command |= rol32(len, MLXBF_I2C_MASTER_READ_SHIFT);
649653
} else {
650-
command = MLXBF_I2C_MASTER_ENABLE_WRITE;
654+
command |= MLXBF_I2C_MASTER_ENABLE_WRITE;
651655
command |= rol32(len, MLXBF_I2C_MASTER_WRITE_SHIFT);
652656
}
653657
command |= rol32(slave, MLXBF_I2C_MASTER_SLV_ADDR_SHIFT);
@@ -682,8 +686,10 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
682686
u8 op_idx, data_idx, data_len, write_len, read_len;
683687
struct mlxbf_i2c_smbus_operation *operation;
684688
u8 read_en, write_en, block_en, pec_en;
685-
u8 slave, flags, addr;
689+
bool stop_after_write = true;
690+
u8 slave, addr;
686691
u8 *read_buf;
692+
u32 flags;
687693
u32 bits;
688694
int ret;
689695

@@ -755,7 +761,16 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
755761
memcpy(data_desc + data_idx,
756762
operation->buffer, operation->length);
757763
data_idx += operation->length;
764+
765+
/*
766+
* The stop condition can be skipped when writing on the bus
767+
* to implement a repeated start condition on the next read
768+
* as required for several SMBus and I2C operations.
769+
*/
770+
if (flags & MLXBF_I2C_F_WRITE_WITHOUT_STOP)
771+
stop_after_write = false;
758772
}
773+
759774
/*
760775
* We assume that read operations are performed only once per
761776
* SMBus transaction. *TBD* protect this statement so it won't
@@ -781,7 +796,7 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
781796

782797
if (write_en) {
783798
ret = mlxbf_i2c_smbus_enable(priv, slave, write_len, block_en,
784-
pec_en, 0);
799+
pec_en, 0, stop_after_write);
785800
if (ret)
786801
goto out_unlock;
787802
}
@@ -791,7 +806,7 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
791806
mlxbf_i2c_smbus_write_data(priv, (const u8 *)&addr, 1,
792807
MLXBF_I2C_MASTER_DATA_DESC_ADDR, true);
793808
ret = mlxbf_i2c_smbus_enable(priv, slave, read_len, block_en,
794-
pec_en, 1);
809+
pec_en, 1, true);
795810
if (!ret) {
796811
/* Get Master GW data descriptor. */
797812
mlxbf_i2c_smbus_read_data(priv, data_desc, read_len + 1,
@@ -897,6 +912,9 @@ mlxbf_i2c_smbus_i2c_block_func(struct mlxbf_i2c_smbus_request *request,
897912
request->operation[0].flags |= pec_check ? MLXBF_I2C_F_SMBUS_PEC : 0;
898913
request->operation[0].buffer = command;
899914

915+
if (read)
916+
request->operation[0].flags |= MLXBF_I2C_F_WRITE_WITHOUT_STOP;
917+
900918
/*
901919
* As specified in the standard, the max number of bytes to read/write
902920
* per block operation is 32 bytes. In Golan code, the controller can

0 commit comments

Comments
 (0)