@@ -108,6 +108,8 @@ LOG_MODULE_REGISTER(i2c_npcx, CONFIG_I2C_LOG_LEVEL);
108
108
#define I2C_RECOVER_SCL_RETRY 10
109
109
#define I2C_RECOVER_SDA_RETRY 3
110
110
111
+ #define NPCX_SMBADDR_SAEN NPCX_SMBADDR1_SAEN /* All the SAEN in SMBADDR is bit_7 */
112
+
111
113
/* Supported I2C bus frequency */
112
114
enum npcx_i2c_freq {
113
115
NPCX_I2C_BUS_SPEED_100KHZ ,
@@ -116,7 +118,14 @@ enum npcx_i2c_freq {
116
118
};
117
119
118
120
enum npcx_i2c_flag {
119
- NPCX_I2C_FLAG_TARGET ,
121
+ NPCX_I2C_FLAG_TARGET1 ,
122
+ NPCX_I2C_FLAG_TARGET2 ,
123
+ NPCX_I2C_FLAG_TARGET3 ,
124
+ NPCX_I2C_FLAG_TARGET4 ,
125
+ NPCX_I2C_FLAG_TARGET5 ,
126
+ NPCX_I2C_FLAG_TARGET6 ,
127
+ NPCX_I2C_FLAG_TARGET7 ,
128
+ NPCX_I2C_FLAG_TARGET8 ,
120
129
NPCX_I2C_FLAG_COUNT ,
121
130
};
122
131
@@ -178,8 +187,9 @@ struct i2c_ctrl_data {
178
187
bool is_configured ; /* is port configured? */
179
188
const struct npcx_i2c_timing_cfg * ptr_speed_confs ;
180
189
#ifdef CONFIG_I2C_TARGET
181
- struct i2c_target_config * target_cfg ;
182
- atomic_t flags ;
190
+ struct i2c_target_config * target_cfg [NPCX_I2C_FLAG_COUNT ];
191
+ uint8_t target_idx ; /* current target_cfg index */
192
+ atomic_t registered_target_mask ;
183
193
/* i2c wake-up callback configuration */
184
194
struct miwu_callback smb_wk_cb ;
185
195
#endif /* CONFIG_I2C_TARGET */
@@ -847,17 +857,19 @@ static void i2c_ctrl_target_isr(const struct device *dev, uint8_t status)
847
857
{
848
858
struct smb_reg * const inst = HAL_I2C_INSTANCE (dev );
849
859
struct i2c_ctrl_data * const data = dev -> data ;
850
- const struct i2c_target_callbacks * target_cb = data -> target_cfg -> callbacks ;
860
+ const struct i2c_target_callbacks * target_cb = NULL ;
851
861
uint8_t val = 0 ;
852
862
853
863
/* A 'Bus Error' has been identified */
854
864
if (IS_BIT_SET (status , NPCX_SMBST_BER )) {
855
865
/* Clear BER Bit */
856
866
inst -> SMBST = BIT (NPCX_SMBST_BER );
857
867
868
+ target_cb = data -> target_cfg [data -> target_idx ]-> callbacks ;
869
+
858
870
/* Notify upper layer the end of transaction */
859
- if (target_cb -> stop ) {
860
- target_cb -> stop (data -> target_cfg );
871
+ if (( target_cb != NULL ) && target_cb -> stop ) {
872
+ target_cb -> stop (data -> target_cfg [ data -> target_idx ] );
861
873
}
862
874
863
875
/* Reset i2c module in target mode */
@@ -887,8 +899,9 @@ static void i2c_ctrl_target_isr(const struct device *dev, uint8_t status)
887
899
/* End of transaction */
888
900
data -> oper_state = NPCX_I2C_IDLE ;
889
901
/* Notify upper layer a STOP condition received */
890
- if (target_cb -> stop ) {
891
- target_cb -> stop (data -> target_cfg );
902
+ target_cb = data -> target_cfg [data -> target_idx ]-> callbacks ;
903
+ if ((target_cb != NULL ) && target_cb -> stop ) {
904
+ target_cb -> stop (data -> target_cfg [data -> target_idx ]);
892
905
}
893
906
894
907
#ifdef CONFIG_PM
@@ -910,39 +923,56 @@ static void i2c_ctrl_target_isr(const struct device *dev, uint8_t status)
910
923
/* Clear NMATCH Bit */
911
924
inst -> SMBST = BIT (NPCX_SMBST_NMATCH );
912
925
926
+ /* Check MATCH1F ~ MATCH7F */
927
+ if (inst -> SMBCST2 & ~BIT (NPCX_SMBCST2_INTSTS )) {
928
+ for (uint8_t addr_idx = NPCX_I2C_FLAG_TARGET1 ;
929
+ addr_idx <= NPCX_I2C_FLAG_TARGET7 ; addr_idx ++ ) {
930
+ if (inst -> SMBCST2 & BIT (addr_idx )) {
931
+ data -> target_idx = addr_idx ;
932
+ break ;
933
+ }
934
+ }
935
+ } else if (inst -> SMBCST3 & BIT (NPCX_SMBCST3_MATCHA8F )) {
936
+ data -> target_idx = NPCX_I2C_FLAG_TARGET8 ;
937
+ }
938
+
939
+ target_cb = data -> target_cfg [data -> target_idx ]-> callbacks ;
940
+
913
941
/* Distinguish the direction of i2c target mode by reading XMIT bit */
914
942
if (IS_BIT_SET (inst -> SMBST , NPCX_SMBST_XMIT )) {
915
943
/* Start transmitting data in i2c target mode */
916
944
data -> oper_state = NPCX_I2C_WRITE_FIFO ;
917
945
/* Write first requested byte after repeated start */
918
- if (target_cb -> read_requested ) {
919
- target_cb -> read_requested (data -> target_cfg , & val );
946
+ if (( target_cb != NULL ) && target_cb -> read_requested ) {
947
+ target_cb -> read_requested (data -> target_cfg [ data -> target_idx ] , & val );
920
948
}
921
949
inst -> SMBSDA = val ;
922
950
} else {
923
951
/* Start receiving data in i2c target mode */
924
952
data -> oper_state = NPCX_I2C_READ_FIFO ;
925
953
926
- if (target_cb -> write_requested ) {
927
- target_cb -> write_requested (data -> target_cfg );
954
+ if (( target_cb != NULL ) && target_cb -> write_requested ) {
955
+ target_cb -> write_requested (data -> target_cfg [ data -> target_idx ] );
928
956
}
929
957
}
930
958
return ;
931
959
}
932
960
933
961
/* Tx byte empty or Rx byte full has occurred */
934
962
if (IS_BIT_SET (status , NPCX_SMBST_SDAST )) {
963
+ target_cb = data -> target_cfg [data -> target_idx ]-> callbacks ;
964
+
935
965
if (data -> oper_state == NPCX_I2C_WRITE_FIFO ) {
936
966
/* Notify upper layer one byte will be transmitted */
937
- if (target_cb -> read_processed ) {
938
- target_cb -> read_processed (data -> target_cfg , & val );
967
+ if (( target_cb != NULL ) && target_cb -> read_processed ) {
968
+ target_cb -> read_processed (data -> target_cfg [ data -> target_idx ] , & val );
939
969
}
940
970
inst -> SMBSDA = val ;
941
971
} else if (data -> oper_state == NPCX_I2C_READ_FIFO ) {
942
- if (target_cb -> write_received ) {
972
+ if (( target_cb != NULL ) && target_cb -> write_received ) {
943
973
val = inst -> SMBSDA ;
944
974
/* Notify upper layer one byte received */
945
- target_cb -> write_received (data -> target_cfg , val );
975
+ target_cb -> write_received (data -> target_cfg [ data -> target_idx ] , val );
946
976
}
947
977
} else {
948
978
LOG_ERR ("Unexpected oper state %d on i2c target port%02x!" ,
@@ -971,7 +1001,7 @@ static void i2c_ctrl_isr(const struct device *dev)
971
1001
LOG_DBG ("status: %02x, %d" , status , data -> oper_state );
972
1002
973
1003
#ifdef CONFIG_I2C_TARGET
974
- if (atomic_test_bit (& data -> flags , NPCX_I2C_FLAG_TARGET ) ) {
1004
+ if (atomic_get (& data -> registered_target_mask ) != ( atomic_val_t ) 0 ) {
975
1005
i2c_ctrl_target_isr (dev , status );
976
1006
return ;
977
1007
}
@@ -1170,6 +1200,34 @@ int npcx_i2c_ctrl_recover_bus(const struct device *dev)
1170
1200
}
1171
1201
1172
1202
#ifdef CONFIG_I2C_TARGET
1203
+ static volatile uint8_t * npcx_i2c_ctrl_target_get_reg_smbaddr (const struct device * i2c_dev ,
1204
+ int index )
1205
+ {
1206
+ struct smb_reg * const inst = HAL_I2C_INSTANCE (i2c_dev );
1207
+
1208
+ switch (index ) {
1209
+ case 0 :
1210
+ return & inst -> SMBADDR1 ;
1211
+ case 1 :
1212
+ return & inst -> SMBADDR2 ;
1213
+ case 2 :
1214
+ return & inst -> SMBADDR3 ;
1215
+ case 3 :
1216
+ return & inst -> SMBADDR4 ;
1217
+ case 4 :
1218
+ return & inst -> SMBADDR5 ;
1219
+ case 5 :
1220
+ return & inst -> SMBADDR6 ;
1221
+ case 6 :
1222
+ return & inst -> SMBADDR7 ;
1223
+ case 7 :
1224
+ return & inst -> SMBADDR8 ;
1225
+ default :
1226
+ LOG_ERR ("Invalid SMBADDR index: %d" , index );
1227
+ return NULL ;
1228
+ }
1229
+ }
1230
+
1173
1231
int npcx_i2c_ctrl_target_register (const struct device * i2c_dev ,
1174
1232
struct i2c_target_config * target_cfg , uint8_t port )
1175
1233
{
@@ -1178,22 +1236,50 @@ int npcx_i2c_ctrl_target_register(const struct device *i2c_dev,
1178
1236
struct i2c_ctrl_data * const data = i2c_dev -> data ;
1179
1237
int idx_ctrl = (port & 0xF0 ) >> 4 ;
1180
1238
int idx_port = (port & 0x0F );
1181
- uint8_t addr = BIT (NPCX_SMBADDR1_SAEN ) | target_cfg -> address ;
1182
-
1183
- /* I2c module has been configured to target mode */
1184
- if (atomic_test_and_set_bit (& data -> flags , NPCX_I2C_FLAG_TARGET )) {
1185
- return - EBUSY ;
1186
- }
1239
+ int avail_addr_slot ;
1240
+ volatile uint8_t * reg_smbaddr ;
1241
+ uint8_t smbaddr_val = BIT (NPCX_SMBADDR_SAEN ) | target_cfg -> address ;
1242
+ uint32_t i2c_tgt_mask = (uint32_t )atomic_get (& data -> registered_target_mask );
1243
+ int addr_idx ;
1187
1244
1188
1245
/* A transiaction is ongoing */
1189
1246
if (data -> oper_state != NPCX_I2C_IDLE ) {
1190
- atomic_clear_bit (& data -> flags , NPCX_I2C_FLAG_TARGET );
1191
1247
return - EBUSY ;
1192
1248
}
1193
1249
1194
- data -> target_cfg = target_cfg ;
1250
+ /* Find valid smbaddr location */
1251
+ avail_addr_slot = find_lsb_set (~i2c_tgt_mask ) - 1 ;
1252
+ if (avail_addr_slot == -1 || avail_addr_slot >= NPCX_I2C_FLAG_COUNT ) {
1253
+ LOG_ERR ("No available smbaddr register, smbaddr_idx: %d" , avail_addr_slot );
1254
+ return - ENOSPC ;
1255
+ }
1256
+
1257
+ /* Check if the address is duplicated */
1258
+ while (i2c_tgt_mask ) {
1259
+ addr_idx = find_lsb_set (i2c_tgt_mask ) - 1 ;
1260
+ reg_smbaddr = npcx_i2c_ctrl_target_get_reg_smbaddr (i2c_dev , addr_idx );
1261
+
1262
+ /* Check if the address is duplicated */
1263
+ if (* reg_smbaddr == smbaddr_val ) {
1264
+ LOG_ERR ("Address %#x is already set" , target_cfg -> address );
1265
+ return - EINVAL ;
1266
+ }
1267
+
1268
+ i2c_tgt_mask &= ~BIT (addr_idx );
1269
+ }
1270
+
1271
+ /* Mark the selected address slot */
1272
+ atomic_set_bit (& data -> registered_target_mask , avail_addr_slot );
1195
1273
1196
1274
i2c_ctrl_irq_enable (i2c_dev , 0 );
1275
+
1276
+ data -> port = port ; /* Update the I2C port index */
1277
+
1278
+ /* Config new address */
1279
+ reg_smbaddr = npcx_i2c_ctrl_target_get_reg_smbaddr (i2c_dev , avail_addr_slot );
1280
+ * reg_smbaddr = smbaddr_val ; /* Set address register */
1281
+ data -> target_cfg [avail_addr_slot ] = target_cfg ; /* Set target config */
1282
+
1197
1283
/* Switch correct port for i2c controller first */
1198
1284
npcx_pinctrl_i2c_port_sel (idx_ctrl , idx_port );
1199
1285
/* Reset I2C module */
@@ -1203,7 +1289,6 @@ int npcx_i2c_ctrl_target_register(const struct device *i2c_dev,
1203
1289
/* Select normal bank and single byte mode for i2c target mode */
1204
1290
i2c_ctrl_bank_sel (i2c_dev , NPCX_I2C_BANK_NORMAL );
1205
1291
inst -> SMBFIF_CTL &= ~BIT (NPCX_SMBFIF_CTL_FIFO_EN );
1206
- inst -> SMBADDR1 = addr ; /* Enable target mode and configure its address */
1207
1292
1208
1293
/* Reconfigure SMBCTL1 */
1209
1294
inst -> SMBCTL1 |= BIT (NPCX_SMBCTL1_NMINTE ) | BIT (NPCX_SMBCTL1_INTEN );
@@ -1218,6 +1303,7 @@ int npcx_i2c_ctrl_target_register(const struct device *i2c_dev,
1218
1303
/* Enable SMB's MIWU interrupts */
1219
1304
npcx_miwu_irq_enable (& config -> smb_wui );
1220
1305
}
1306
+
1221
1307
i2c_ctrl_irq_enable (i2c_dev , 1 );
1222
1308
1223
1309
return 0 ;
@@ -1230,44 +1316,78 @@ int npcx_i2c_ctrl_target_unregister(const struct device *i2c_dev,
1230
1316
const struct i2c_ctrl_config * const config = i2c_dev -> config ;
1231
1317
struct i2c_ctrl_data * const data = i2c_dev -> data ;
1232
1318
int idx_ctrl = (port & 0xF0 ) >> 4 ;
1319
+ int cur_addr_slot ;
1320
+ volatile uint8_t * reg_smbaddr ;
1321
+ uint8_t smbaddr_val = BIT (NPCX_SMBADDR_SAEN ) | target_cfg -> address ;
1322
+ uint32_t i2c_tgt_mask = (uint32_t )atomic_get (& data -> registered_target_mask );
1233
1323
1234
1324
/* No I2c module has been configured to target mode */
1235
- if (!atomic_test_bit (& data -> flags , NPCX_I2C_FLAG_TARGET )) {
1325
+ if (atomic_get (& data -> registered_target_mask ) == (atomic_val_t ) 0 ) {
1326
+ LOG_ERR ("No available target to ungister" );
1236
1327
return - EINVAL ;
1237
1328
}
1238
1329
1239
1330
/* A transiaction is ongoing */
1240
1331
if (data -> oper_state != NPCX_I2C_IDLE ) {
1241
1332
return - EBUSY ;
1242
1333
}
1243
- data -> target_cfg = NULL ;
1334
+
1335
+ /* Find target address in smbaddr */
1336
+ while (i2c_tgt_mask ) {
1337
+ cur_addr_slot = find_lsb_set (i2c_tgt_mask ) - 1 ;
1338
+ reg_smbaddr = npcx_i2c_ctrl_target_get_reg_smbaddr (i2c_dev , cur_addr_slot );
1339
+ if (reg_smbaddr == NULL ) {
1340
+ LOG_ERR ("Invalid smbaddr register" );
1341
+ return - EINVAL ;
1342
+ }
1343
+
1344
+ /* Target address found */
1345
+ if (* reg_smbaddr == smbaddr_val ) {
1346
+ break ;
1347
+ }
1348
+
1349
+ i2c_tgt_mask &= ~BIT (cur_addr_slot );
1350
+ }
1351
+
1352
+ /* Input addrss is not in the smbaddr */
1353
+ if (i2c_tgt_mask == 0 || reg_smbaddr == NULL ) {
1354
+ LOG_ERR ("Address %#x is not found" , target_cfg -> address );
1355
+ return - EINVAL ;
1356
+ }
1244
1357
1245
1358
i2c_ctrl_irq_enable (i2c_dev , 0 );
1246
- /* Reset I2C module */
1247
- inst -> SMBCTL2 &= ~BIT (NPCX_SMBCTL2_ENABLE );
1248
- inst -> SMBCTL2 |= BIT (NPCX_SMBCTL2_ENABLE );
1249
1359
1250
- inst -> SMBADDR1 = 0 ; /* Disable target mode and clear address setting */
1251
- /* Enable FIFO mode and select to FIFO bank for i2c controller mode */
1252
- inst -> SMBFIF_CTL |= BIT (NPCX_SMBFIF_CTL_FIFO_EN );
1253
- i2c_ctrl_bank_sel (i2c_dev , NPCX_I2C_BANK_FIFO );
1360
+ * reg_smbaddr = 0 ; /* Disable target mode and clear address setting */
1361
+ data -> target_cfg [cur_addr_slot ] = NULL ; /* Clear target config */
1254
1362
1255
- /* Reconfigure SMBCTL1 */
1256
- inst -> SMBCTL1 |= BIT ( NPCX_SMBCTL1_NMINTE ) | BIT ( NPCX_SMBCTL1_INTEN );
1363
+ /* Mark it as controller mode */
1364
+ atomic_clear_bit ( & data -> registered_target_mask , cur_addr_slot );
1257
1365
1258
- /* Disable irq of smb wake-up event */
1259
- if (IS_ENABLED (CONFIG_PM )) {
1260
- /* Disable SMB wake up detection */
1261
- npcx_i2c_target_start_wk_enable (idx_ctrl , false);
1262
- /* Disable start detect in IDLE */
1263
- inst -> SMBCTL3 &= ~BIT (NPCX_SMBCTL3_IDL_START );
1264
- /* Disable SMB's MIWU interrupts */
1265
- npcx_miwu_irq_disable (& config -> smb_wui );
1366
+ /* Switch I2C to controller mode if no any other valid address in smbaddr */
1367
+ if (atomic_get (& data -> registered_target_mask ) == (atomic_val_t ) 0 ) {
1368
+ /* Reset I2C module */
1369
+ inst -> SMBCTL2 &= ~BIT (NPCX_SMBCTL2_ENABLE );
1370
+ inst -> SMBCTL2 |= BIT (NPCX_SMBCTL2_ENABLE );
1266
1371
1372
+ /* Enable FIFO mode and select to FIFO bank for i2c controller mode */
1373
+ inst -> SMBFIF_CTL |= BIT (NPCX_SMBFIF_CTL_FIFO_EN );
1374
+ i2c_ctrl_bank_sel (i2c_dev , NPCX_I2C_BANK_FIFO );
1375
+
1376
+ /* Reconfigure SMBCTL1 */
1377
+ inst -> SMBCTL1 |= BIT (NPCX_SMBCTL1_NMINTE ) | BIT (NPCX_SMBCTL1_INTEN );
1378
+
1379
+ /* Disable irq of smb wake-up event */
1380
+ if (IS_ENABLED (CONFIG_PM )) {
1381
+ /* Disable SMB wake up detection */
1382
+ npcx_i2c_target_start_wk_enable (idx_ctrl , false);
1383
+ /* Disable start detect in IDLE */
1384
+ inst -> SMBCTL3 &= ~BIT (NPCX_SMBCTL3_IDL_START );
1385
+ /* Disable SMB's MIWU interrupts */
1386
+ npcx_miwu_irq_disable (& config -> smb_wui );
1387
+ }
1267
1388
}
1389
+
1268
1390
i2c_ctrl_irq_enable (i2c_dev , 1 );
1269
- /* Mark it as controller mode */
1270
- atomic_clear_bit (& data -> flags , NPCX_I2C_FLAG_TARGET );
1271
1391
1272
1392
return 0 ;
1273
1393
}
@@ -1304,7 +1424,7 @@ int npcx_i2c_ctrl_transfer(const struct device *i2c_dev, struct i2c_msg *msgs,
1304
1424
1305
1425
#ifdef CONFIG_I2C_TARGET
1306
1426
/* I2c module has been configured to target mode */
1307
- if (atomic_test_bit (& data -> flags , NPCX_I2C_FLAG_TARGET ) ) {
1427
+ if (atomic_get (& data -> registered_target_mask ) != ( atomic_val_t ) 0 ) {
1308
1428
return - EBUSY ;
1309
1429
}
1310
1430
#endif /* CONFIG_I2C_TARGET */
0 commit comments