@@ -30,13 +30,30 @@ struct i2c_cc23x0_data {
3030 struct k_sem lock ;
3131 struct k_sem complete ;
3232 volatile uint32_t error ;
33+ uint32_t cfg ;
3334};
3435
3536struct i2c_cc23x0_config {
3637 uint32_t base ;
3738 const struct pinctrl_dev_config * pcfg ;
3839};
3940
41+ static inline void i2c_cc23x0_pm_policy_state_lock_get (void )
42+ {
43+ #ifdef CONFIG_PM_DEVICE
44+ pm_policy_state_lock_get (PM_STATE_RUNTIME_IDLE , PM_ALL_SUBSTATES );
45+ pm_policy_state_lock_get (PM_STATE_STANDBY , PM_ALL_SUBSTATES );
46+ #endif
47+ }
48+
49+ static inline void i2c_cc23x0_pm_policy_state_lock_put (void )
50+ {
51+ #ifdef CONFIG_PM_DEVICE
52+ pm_policy_state_lock_put (PM_STATE_RUNTIME_IDLE , PM_ALL_SUBSTATES );
53+ pm_policy_state_lock_put (PM_STATE_STANDBY , PM_ALL_SUBSTATES );
54+ #endif
55+ }
56+
4057static int i2c_cc23x0_transmit (const struct device * dev , const uint8_t * buf , uint32_t len ,
4158 uint16_t addr )
4259{
@@ -53,7 +70,7 @@ static int i2c_cc23x0_transmit(const struct device *dev, const uint8_t *buf, uin
5370
5471 /* Single transmission */
5572 if (len == 1 ) {
56- I2CControllerPutData (base , * buf );
73+ I2CControllerPutData (base , buf [ 0 ] );
5774 I2CControllerCommand (base , I2C_CONTROLLER_CMD_SINGLE_SEND );
5875 k_sem_take (& data -> complete , K_FOREVER );
5976 return data -> error == I2C_MASTER_ERR_NONE ? 0 : - EIO ;
@@ -103,18 +120,19 @@ static int i2c_cc23x0_receive(const struct device *dev, uint8_t *buf, uint32_t l
103120 if (len == 0 ) {
104121 return - EIO ;
105122 }
106- I2CControllerSetTargetAddr (base , addr , true);
107123
124+ I2CControllerSetTargetAddr (base , addr , true);
108125 /* Single receive */
109126 if (len == 1 ) {
127+ buf [0 ] = I2CControllerGetData (base );
110128 I2CControllerCommand (base , I2C_CONTROLLER_CMD_SINGLE_RECEIVE );
129+
111130 k_sem_take (& data -> complete , K_FOREVER );
112131
113132 if (data -> error != I2C_MASTER_ERR_NONE ) {
114133 return - EIO ;
115134 }
116-
117- * buf = I2CControllerGetData (base );
135+ buf [0 ] = I2CControllerGetData (base );
118136 return 0 ;
119137 }
120138
@@ -127,7 +145,6 @@ static int i2c_cc23x0_receive(const struct device *dev, uint8_t *buf, uint32_t l
127145 }
128146
129147 buf [0 ] = I2CControllerGetData (base );
130-
131148 for (int i = 1 ; i < len - 1 ; i ++ ) {
132149 I2CControllerCommand (base , I2C_CONTROLLER_CMD_BURST_RECEIVE_CONT );
133150 k_sem_take (& data -> complete , K_FOREVER );
@@ -159,6 +176,7 @@ static int i2c_cc23x0_transfer(const struct device *dev, struct i2c_msg *msgs, u
159176 uint16_t addr )
160177{
161178 struct i2c_cc23x0_data * data = dev -> data ;
179+ const struct i2c_cc23x0_config * config = dev -> config ;
162180 int ret = 0 ;
163181
164182 if (num_msgs == 0 ) {
@@ -167,6 +185,8 @@ static int i2c_cc23x0_transfer(const struct device *dev, struct i2c_msg *msgs, u
167185
168186 k_sem_take (& data -> lock , K_FOREVER );
169187
188+ i2c_cc23x0_pm_policy_state_lock_get ();
189+
170190 for (int i = 0 ; i < num_msgs ; i ++ ) {
171191 /* Not supported by hardware */
172192 if (msgs [i ].flags & I2C_MSG_ADDR_10_BITS ) {
@@ -184,6 +204,13 @@ static int i2c_cc23x0_transfer(const struct device *dev, struct i2c_msg *msgs, u
184204 break ;
185205 }
186206 }
207+
208+ while (I2CControllerBusy (config -> base )) {
209+ ;
210+ }
211+
212+ i2c_cc23x0_pm_policy_state_lock_put ();
213+
187214 k_sem_give (& data -> lock );
188215
189216 return ret ;
@@ -227,6 +254,33 @@ static int i2c_cc23x0_configure(const struct device *dev, uint32_t dev_config)
227254 return 0 ;
228255}
229256
257+ #ifdef CONFIG_PM_DEVICE
258+
259+ static int i2c_cc23x0_pm_action (const struct device * dev , enum pm_device_action action )
260+ {
261+ const struct i2c_cc23x0_config * config = dev -> config ;
262+ struct i2c_cc23x0_data * data = dev -> data ;
263+
264+ switch (action ) {
265+ case PM_DEVICE_ACTION_SUSPEND :
266+ I2CControllerDisable (config -> base );
267+ I2CControllerDisableInt (config -> base );
268+ CLKCTLDisable (CLKCTL_BASE , CLKCTL_I2C0 );
269+ break ;
270+ case PM_DEVICE_ACTION_RESUME :
271+ CLKCTLEnable (CLKCTL_BASE , CLKCTL_I2C0 );
272+ i2c_cc23x0_configure (dev , data -> cfg | I2C_MODE_CONTROLLER );
273+ I2CControllerEnableInt (config -> base );
274+ break ;
275+ default :
276+ return - ENOTSUP ;
277+ }
278+
279+ return 0 ;
280+ }
281+
282+ #endif /* CONFIG_PM_DEVICE */
283+
230284static void i2c_cc23x0_isr (const struct device * dev )
231285{
232286 const struct i2c_cc23x0_config * config = dev -> config ;
@@ -237,8 +291,12 @@ static void i2c_cc23x0_isr(const struct device *dev)
237291 I2CControllerClearInt (base );
238292
239293 data -> error = I2CControllerError (base );
240-
241- k_sem_give (& data -> complete );
294+ if (data -> error ) {
295+ LOG_ERR ("Error [%x]" , data -> error );
296+ }
297+ if (!I2CControllerBusy (config -> base )) {
298+ k_sem_give (& data -> complete );
299+ }
242300 }
243301}
244302
@@ -290,8 +348,8 @@ static const struct i2c_driver_api i2c_cc23x0_driver_api = {.configure = i2c_cc2
290348 .complete = Z_SEM_INITIALIZER(i2c_cc23x0_##id##_data.complete, 0, 1), \
291349 .error = I2C_MASTER_ERR_NONE}; \
292350 \
293- I2C_DEVICE_DT_INST_DEFINE(id, i2c_cc23x0_init##id, NULL, &i2c_cc23x0_##id##_data, \
294- &i2c_cc23x0_##id##_config, POST_KERNEL, \
351+ I2C_DEVICE_DT_INST_DEFINE(id, i2c_cc23x0_init##id, PM_DEVICE_DT_INST_GET(id), \
352+ &i2c_cc23x0_##id##_data, &i2c_cc23x0_##id## _config, POST_KERNEL, \
295353 CONFIG_I2C_INIT_PRIORITY, &i2c_cc23x0_driver_api);
296354
297355DT_INST_FOREACH_STATUS_OKAY (CC23X0_I2C );
0 commit comments