@@ -108,6 +108,8 @@ LOG_MODULE_REGISTER(i2c_npcx, CONFIG_I2C_LOG_LEVEL);
108108#define I2C_RECOVER_SCL_RETRY 10
109109#define I2C_RECOVER_SDA_RETRY 3
110110
111+ #define NPCX_SMBADDR_SAEN NPCX_SMBADDR1_SAEN /* All the SAEN in SMBADDR is bit_7 */
112+
111113/* Supported I2C bus frequency */
112114enum npcx_i2c_freq {
113115 NPCX_I2C_BUS_SPEED_100KHZ ,
@@ -116,7 +118,14 @@ enum npcx_i2c_freq {
116118};
117119
118120enum 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 ,
120129 NPCX_I2C_FLAG_COUNT ,
121130};
122131
@@ -178,8 +187,9 @@ struct i2c_ctrl_data {
178187 bool is_configured ; /* is port configured? */
179188 const struct npcx_i2c_timing_cfg * ptr_speed_confs ;
180189#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 ;
183193 /* i2c wake-up callback configuration */
184194 struct miwu_callback smb_wk_cb ;
185195#endif /* CONFIG_I2C_TARGET */
@@ -847,17 +857,19 @@ static void i2c_ctrl_target_isr(const struct device *dev, uint8_t status)
847857{
848858 struct smb_reg * const inst = HAL_I2C_INSTANCE (dev );
849859 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 ;
851861 uint8_t val = 0 ;
852862
853863 /* A 'Bus Error' has been identified */
854864 if (IS_BIT_SET (status , NPCX_SMBST_BER )) {
855865 /* Clear BER Bit */
856866 inst -> SMBST = BIT (NPCX_SMBST_BER );
857867
868+ target_cb = data -> target_cfg [data -> target_idx ]-> callbacks ;
869+
858870 /* 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 ] );
861873 }
862874
863875 /* Reset i2c module in target mode */
@@ -887,8 +899,9 @@ static void i2c_ctrl_target_isr(const struct device *dev, uint8_t status)
887899 /* End of transaction */
888900 data -> oper_state = NPCX_I2C_IDLE ;
889901 /* 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 ]);
892905 }
893906
894907#ifdef CONFIG_PM
@@ -910,39 +923,56 @@ static void i2c_ctrl_target_isr(const struct device *dev, uint8_t status)
910923 /* Clear NMATCH Bit */
911924 inst -> SMBST = BIT (NPCX_SMBST_NMATCH );
912925
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+
913941 /* Distinguish the direction of i2c target mode by reading XMIT bit */
914942 if (IS_BIT_SET (inst -> SMBST , NPCX_SMBST_XMIT )) {
915943 /* Start transmitting data in i2c target mode */
916944 data -> oper_state = NPCX_I2C_WRITE_FIFO ;
917945 /* 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 );
920948 }
921949 inst -> SMBSDA = val ;
922950 } else {
923951 /* Start receiving data in i2c target mode */
924952 data -> oper_state = NPCX_I2C_READ_FIFO ;
925953
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 ] );
928956 }
929957 }
930958 return ;
931959 }
932960
933961 /* Tx byte empty or Rx byte full has occurred */
934962 if (IS_BIT_SET (status , NPCX_SMBST_SDAST )) {
963+ target_cb = data -> target_cfg [data -> target_idx ]-> callbacks ;
964+
935965 if (data -> oper_state == NPCX_I2C_WRITE_FIFO ) {
936966 /* 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 );
939969 }
940970 inst -> SMBSDA = val ;
941971 } else if (data -> oper_state == NPCX_I2C_READ_FIFO ) {
942- if (target_cb -> write_received ) {
972+ if (( target_cb != NULL ) && target_cb -> write_received ) {
943973 val = inst -> SMBSDA ;
944974 /* 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 );
946976 }
947977 } else {
948978 LOG_ERR ("Unexpected oper state %d on i2c target port%02x!" ,
@@ -971,7 +1001,7 @@ static void i2c_ctrl_isr(const struct device *dev)
9711001 LOG_DBG ("status: %02x, %d" , status , data -> oper_state );
9721002
9731003#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 ) {
9751005 i2c_ctrl_target_isr (dev , status );
9761006 return ;
9771007 }
@@ -1170,6 +1200,34 @@ int npcx_i2c_ctrl_recover_bus(const struct device *dev)
11701200}
11711201
11721202#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+
11731231int npcx_i2c_ctrl_target_register (const struct device * i2c_dev ,
11741232 struct i2c_target_config * target_cfg , uint8_t port )
11751233{
@@ -1178,22 +1236,50 @@ int npcx_i2c_ctrl_target_register(const struct device *i2c_dev,
11781236 struct i2c_ctrl_data * const data = i2c_dev -> data ;
11791237 int idx_ctrl = (port & 0xF0 ) >> 4 ;
11801238 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 ;
11871244
11881245 /* A transiaction is ongoing */
11891246 if (data -> oper_state != NPCX_I2C_IDLE ) {
1190- atomic_clear_bit (& data -> flags , NPCX_I2C_FLAG_TARGET );
11911247 return - EBUSY ;
11921248 }
11931249
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 );
11951273
11961274 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+
11971283 /* Switch correct port for i2c controller first */
11981284 npcx_pinctrl_i2c_port_sel (idx_ctrl , idx_port );
11991285 /* Reset I2C module */
@@ -1203,7 +1289,6 @@ int npcx_i2c_ctrl_target_register(const struct device *i2c_dev,
12031289 /* Select normal bank and single byte mode for i2c target mode */
12041290 i2c_ctrl_bank_sel (i2c_dev , NPCX_I2C_BANK_NORMAL );
12051291 inst -> SMBFIF_CTL &= ~BIT (NPCX_SMBFIF_CTL_FIFO_EN );
1206- inst -> SMBADDR1 = addr ; /* Enable target mode and configure its address */
12071292
12081293 /* Reconfigure SMBCTL1 */
12091294 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,
12181303 /* Enable SMB's MIWU interrupts */
12191304 npcx_miwu_irq_enable (& config -> smb_wui );
12201305 }
1306+
12211307 i2c_ctrl_irq_enable (i2c_dev , 1 );
12221308
12231309 return 0 ;
@@ -1230,44 +1316,78 @@ int npcx_i2c_ctrl_target_unregister(const struct device *i2c_dev,
12301316 const struct i2c_ctrl_config * const config = i2c_dev -> config ;
12311317 struct i2c_ctrl_data * const data = i2c_dev -> data ;
12321318 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 );
12331323
12341324 /* 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" );
12361327 return - EINVAL ;
12371328 }
12381329
12391330 /* A transiaction is ongoing */
12401331 if (data -> oper_state != NPCX_I2C_IDLE ) {
12411332 return - EBUSY ;
12421333 }
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+ }
12441357
12451358 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 );
12491359
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 */
12541362
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 );
12571365
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 );
12661371
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+ }
12671388 }
1389+
12681390 i2c_ctrl_irq_enable (i2c_dev , 1 );
1269- /* Mark it as controller mode */
1270- atomic_clear_bit (& data -> flags , NPCX_I2C_FLAG_TARGET );
12711391
12721392 return 0 ;
12731393}
@@ -1304,7 +1424,7 @@ int npcx_i2c_ctrl_transfer(const struct device *i2c_dev, struct i2c_msg *msgs,
13041424
13051425#ifdef CONFIG_I2C_TARGET
13061426 /* 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 ) {
13081428 return - EBUSY ;
13091429 }
13101430#endif /* CONFIG_I2C_TARGET */
0 commit comments