1- /* dw_i2c .c - I2C file for Design Ware */
1+ /* i2c_dw .c - I2C file for Design Ware */
22
33/*
4- * Copyright (c) 2015 Intel Corporation
54 * Copyright (c) 2022 Andrei-Edward Popa
5+ * Copyright (c) 2015-2023 Intel Corporation
66 *
77 * SPDX-License-Identifier: Apache-2.0
88 */
@@ -351,7 +351,7 @@ static inline void i2c_dw_transfer_complete(const struct device *dev)
351351}
352352
353353#ifdef CONFIG_I2C_TARGET
354- static inline uint8_t i2c_dw_read_byte_non_blocking (const struct device * dev );
354+ static inline int i2c_dw_read_byte_non_blocking (const struct device * dev , uint8_t * data );
355355static inline void i2c_dw_write_byte_non_blocking (const struct device * dev , uint8_t data );
356356static void i2c_dw_slave_read_clear_intr_bits (const struct device * dev );
357357#endif
@@ -364,8 +364,8 @@ static void i2c_dw_isr(const struct device *port)
364364 int ret = 0 ;
365365 uint32_t reg_base = get_regs (port );
366366
367- /* Cache ic_intr_stat for processing, so there is no need to read
368- * the register multiple times.
367+ /* Cache I2C Interrupt Status Register( ic_intr_stat) for processing,
368+ * so there is no need to read the register multiple times.
369369 */
370370 intr_stat .raw = read_intr_stat (reg_base );
371371
@@ -512,7 +512,7 @@ static int i2c_dw_setup(const struct device *dev, uint16_t slave_address)
512512 * Make sure to set both the master_mode and slave_disable_bit
513513 * to both 0 or both 1
514514 */
515- LOG_DBG ("I2C: host configured as Master Device" );
515+ LOG_DBG ("I2C: host configured as Controller Device" );
516516 ic_con .bits .master_mode = 1U ;
517517 ic_con .bits .slave_disable = 1U ;
518518 } else {
@@ -619,7 +619,7 @@ static int i2c_dw_transfer(const struct device *dev, struct i2c_msg *msgs, uint8
619619{
620620 struct i2c_dw_dev_config * const dw = dev -> data ;
621621 struct i2c_msg * cur_msg = msgs ;
622- uint8_t msg_left = num_msgs ;
622+ uint8_t msg_left ;
623623 uint8_t pflags ;
624624 int ret ;
625625 uint32_t reg_base = get_regs (dev );
@@ -635,6 +635,21 @@ static int i2c_dw_transfer(const struct device *dev, struct i2c_msg *msgs, uint8
635635 return ret ;
636636 }
637637
638+ /*
639+ * I2C transfer with 0 length are invalid but
640+ * SMbus quick commands uses 0 length transfer.
641+ * And in order to support SMbus quick commands, the driver
642+ * has to be enhanced.
643+ */
644+ for (msg_left = 0 ; msg_left < num_msgs ; msg_left ++ ) {
645+ if (msgs [msg_left ].len == 0 ) {
646+ LOG_ERR ("Invalid transfer length 0 for msgs[%d]" , msg_left );
647+ return - EINVAL ;
648+ }
649+ }
650+
651+ msg_left = num_msgs ;
652+
638653 /* First step, check if there is current activity */
639654 if (test_bit_status_activity (reg_base ) || (dw -> state & I2C_DW_BUSY )) {
640655 ret = - EBUSY ;
@@ -741,14 +756,13 @@ static int i2c_dw_runtime_configure(const struct device *dev, uint32_t config)
741756 struct i2c_dw_dev_config * const dw = dev -> data ;
742757 const struct i2c_dw_rom_config * const rom = dev -> config ;
743758 uint32_t value = 0U ;
744- uint32_t rc = 0U ;
759+ uint32_t ret = 0U ;
745760 uint32_t reg_base = get_regs (dev );
746761
747- dw -> app_config = config ;
748762
749763 /* Make sure we have a supported speed for the DesignWare model */
750764 /* and have setup the clock frequency and speed mode */
751- switch (I2C_SPEED_GET (dw -> app_config )) {
765+ switch (I2C_SPEED_GET (config )) {
752766 case I2C_SPEED_STANDARD :
753767 /* Following the directions on DW spec page 59, IC_SS_SCL_LCNT
754768 * must have register values larger than IC_FS_SPKLEN + 7
@@ -832,14 +846,17 @@ static int i2c_dw_runtime_configure(const struct device *dev, uint32_t config)
832846
833847 dw -> hcnt = value ;
834848 } else {
835- rc = - EINVAL ;
849+ ret = - EINVAL ;
836850 }
837851 break ;
838852 default :
839853 /* TODO change */
840- rc = - EINVAL ;
854+ ret = - EINVAL ;
841855 }
842856
857+ if (ret == 0 ) {
858+ dw -> app_config = config ;
859+ }
843860 /*
844861 * Clear any interrupts currently waiting in the controller
845862 */
@@ -852,26 +869,30 @@ static int i2c_dw_runtime_configure(const struct device *dev, uint32_t config)
852869 */
853870 dw -> app_config |= I2C_MODE_CONTROLLER ;
854871
855- return rc ;
872+ return ret ;
856873}
857874
858875#ifdef CONFIG_I2C_TARGET
859- static inline uint8_t i2c_dw_read_byte_non_blocking (const struct device * dev )
876+ static inline int i2c_dw_read_byte_non_blocking (const struct device * dev , uint8_t * data )
860877{
861878 uint32_t reg_base = get_regs (dev );
862879
863880 if (!test_bit_status_rfne (reg_base )) { /* Rx FIFO must not be empty */
881+ LOG_ERR ("Rx FIFO is empty" );
864882 return - EIO ;
865883 }
866884
867- return (uint8_t )read_cmd_data (reg_base );
885+ * data = (uint8_t )read_cmd_data (reg_base );
886+
887+ return 0 ;
868888}
869889
870890static inline void i2c_dw_write_byte_non_blocking (const struct device * dev , uint8_t data )
871891{
872892 uint32_t reg_base = get_regs (dev );
873893
874894 if (!test_bit_status_tfnt (reg_base )) { /* Tx FIFO must not be full */
895+ LOG_ERR ("Tx FIFO is full" );
875896 return ;
876897 }
877898
@@ -925,7 +946,7 @@ static int i2c_dw_set_slave_mode(const struct device *dev, uint8_t addr)
925946 write_tx_tl (0 , reg_base );
926947 write_rx_tl (0 , reg_base );
927948
928- LOG_DBG ("I2C: Host registered as Slave Device" );
949+ LOG_DBG ("I2C: Host registered as Target Device" );
929950
930951 return 0 ;
931952}
@@ -947,13 +968,11 @@ static int i2c_dw_slave_register(const struct device *dev, struct i2c_target_con
947968
948969static int i2c_dw_slave_unregister (const struct device * dev , struct i2c_target_config * cfg )
949970{
950- struct i2c_dw_dev_config * const dw = dev -> data ;
951- int ret ;
971+ struct i2c_dw_dev_config * const dw = dev -> data ;
952972
953973 dw -> state = I2C_DW_STATE_READY ;
954- ret = i2c_dw_set_master_mode (dev );
955974
956- return ret ;
975+ return ( int ) i2c_dw_set_master_mode ( dev ) ;
957976}
958977
959978static void i2c_dw_slave_read_clear_intr_bits (const struct device * dev )
0 commit comments