@@ -159,6 +159,15 @@ struct i2c_msg {
159159 uint8_t flags ;
160160};
161161
162+ /**
163+ * @brief I2C callback for asynchronous transfer requests
164+ *
165+ * @param dev I2C device which is notifying of transfer completion or error
166+ * @param result Result code of the transfer request. 0 is success, -errno for failure.
167+ * @param data Transfer requester supplied data which is passed along to the callback.
168+ */
169+ typedef void (* i2c_callback_t )(const struct device * dev , int result , void * data );
170+
162171/**
163172 * @cond INTERNAL_HIDDEN
164173 *
@@ -179,6 +188,14 @@ typedef int (*i2c_api_target_register_t)(const struct device *dev,
179188 struct i2c_target_config * cfg );
180189typedef int (* i2c_api_target_unregister_t )(const struct device * dev ,
181190 struct i2c_target_config * cfg );
191+ #ifdef CONFIG_I2C_CALLBACK
192+ typedef int (* i2c_api_transfer_cb_t )(const struct device * dev ,
193+ struct i2c_msg * msgs ,
194+ uint8_t num_msgs ,
195+ uint16_t addr ,
196+ i2c_callback_t cb ,
197+ void * userdata );
198+ #endif /* CONFIG_I2C_CALLBACK */
182199typedef int (* i2c_api_recover_bus_t )(const struct device * dev );
183200
184201__subsystem struct i2c_driver_api {
@@ -187,6 +204,9 @@ __subsystem struct i2c_driver_api {
187204 i2c_api_full_io_t transfer ;
188205 i2c_api_target_register_t target_register ;
189206 i2c_api_target_unregister_t target_unregister ;
207+ #ifdef CONFIG_I2C_CALLBACK
208+ i2c_api_transfer_cb_t transfer_cb ;
209+ #endif
190210 i2c_api_recover_bus_t recover_bus ;
191211};
192212
@@ -602,6 +622,92 @@ static inline int z_impl_i2c_transfer(const struct device *dev,
602622 return res ;
603623}
604624
625+ #ifdef CONFIG_I2C_CALLBACK
626+
627+ /**
628+ * @brief Perform data transfer to another I2C device in controller mode.
629+ *
630+ * This routine provides a generic interface to perform data transfer
631+ * to another I2C device asynchronously with a callback completion.
632+ *
633+ * @see i2c_transfer()
634+ * @funcprop \isr_ok
635+ *
636+ * @param dev Pointer to the device structure for an I2C controller
637+ * driver configured in controller mode.
638+ * @param msgs Array of messages to transfer, must live until callback completes.
639+ * @param num_msgs Number of messages to transfer.
640+ * @param addr Address of the I2C target device.
641+ * @param cb Function pointer for completion callback.
642+ * @param userdata Userdata passed to callback.
643+ *
644+ * @retval 0 If successful.
645+ * @retval -EIO General input / output error.
646+ * @retval -ENOSYS If transfer async is not implemented
647+ * @retval -EWOULDBLOCK If the device is temporarily busy doing another transfer
648+ */
649+ static inline int i2c_transfer_cb (const struct device * dev ,
650+ struct i2c_msg * msgs ,
651+ uint8_t num_msgs ,
652+ uint16_t addr ,
653+ i2c_callback_t cb ,
654+ void * userdata )
655+ {
656+ const struct i2c_driver_api * api = (const struct i2c_driver_api * )dev -> api ;
657+
658+ if (api -> transfer_cb == NULL ) {
659+ return - ENOSYS ;
660+ }
661+
662+ return api -> transfer_cb (dev , msgs , num_msgs , addr , cb , userdata );
663+ }
664+
665+ #ifdef CONFIG_POLL
666+
667+ /** @cond INTERNAL_HIDDEN */
668+ void z_i2c_transfer_signal_cb (const struct device * dev , int result , void * userdata );
669+ /** @endcond */
670+
671+ /**
672+ * @brief Perform data transfer to another I2C device in controller mode.
673+ *
674+ * This routine provides a generic interface to perform data transfer
675+ * to another I2C device asynchronously with a k_poll_signal completion.
676+ *
677+ * @see i2c_transfer_cb()
678+ * @funcprop \isr_ok
679+ *
680+ * @param dev Pointer to the device structure for an I2C controller
681+ * driver configured in controller mode.
682+ * @param msgs Array of messages to transfer, must live until callback completes.
683+ * @param num_msgs Number of messages to transfer.
684+ * @param addr Address of the I2C target device.
685+ * @param signal Signal to notify of transfer completion.
686+ *
687+ * @retval 0 If successful.
688+ * @retval -EIO General input / output error.
689+ * @retval -ENOSYS If transfer async is not implemented
690+ * @retval -EWOULDBLOCK If the device is temporarily busy doing another transfer
691+ */
692+ static inline int i2c_transfer_signal (const struct device * dev ,
693+ struct i2c_msg * msgs ,
694+ uint8_t num_msgs ,
695+ uint16_t addr ,
696+ struct k_poll_signal * sig )
697+ {
698+ const struct i2c_driver_api * api = (const struct i2c_driver_api * )dev -> api ;
699+
700+ if (api -> transfer_cb == NULL ) {
701+ return - ENOSYS ;
702+ }
703+
704+ return api -> transfer_cb (dev , msgs , num_msgs , addr , z_i2c_transfer_signal_cb , sig );
705+ }
706+
707+ #endif /* CONFIG_POLL */
708+
709+ #endif /* CONFIG_I2C_CALLBACK */
710+
605711/**
606712 * @brief Perform data transfer to another I2C device in controller mode.
607713 *
0 commit comments