7
7
8
8
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
9
9
#include <zephyr/drivers/clock_control.h>
10
+ #include <zephyr/pm/device.h>
10
11
#include <zephyr/sys/util.h>
11
12
#include <zephyr/kernel.h>
12
13
#include <soc.h>
@@ -65,9 +66,13 @@ int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config)
65
66
data -> dev_config = config ;
66
67
67
68
k_sem_take (& data -> bus_mutex , K_FOREVER );
69
+ pm_device_busy_set (dev );
70
+
68
71
LL_I2C_Disable (i2c );
69
72
LL_I2C_SetMode (i2c , LL_I2C_MODE_I2C );
70
73
ret = stm32_i2c_configure_timing (dev , clock );
74
+
75
+ pm_device_busy_clear (dev );
71
76
k_sem_give (& data -> bus_mutex );
72
77
73
78
return ret ;
@@ -179,6 +184,9 @@ static int i2c_stm32_transfer(const struct device *dev, struct i2c_msg *msg,
179
184
/* Send out messages */
180
185
k_sem_take (& data -> bus_mutex , K_FOREVER );
181
186
187
+ /* Prevent driver from being suspended by PM until I2C transaction is complete */
188
+ pm_device_busy_set (dev );
189
+
182
190
current = msg ;
183
191
184
192
while (num_msgs > 0 ) {
@@ -196,6 +204,8 @@ static int i2c_stm32_transfer(const struct device *dev, struct i2c_msg *msg,
196
204
num_msgs -- ;
197
205
}
198
206
207
+ pm_device_busy_clear (dev );
208
+
199
209
k_sem_give (& data -> bus_mutex );
200
210
return ret ;
201
211
}
@@ -209,6 +219,59 @@ static const struct i2c_driver_api api_funcs = {
209
219
#endif
210
220
};
211
221
222
+ #ifdef CONFIG_PM_DEVICE
223
+
224
+ static int i2c_stm32_suspend (const struct device * dev )
225
+ {
226
+ int ret ;
227
+ const struct i2c_stm32_config * cfg = dev -> config ;
228
+ const struct device * const clk = DEVICE_DT_GET (STM32_CLOCK_CONTROL_NODE );
229
+
230
+ /* Disable device clock. */
231
+ ret = clock_control_off (clk , (clock_control_subsys_t )& cfg -> pclken [0 ]);
232
+ if (ret < 0 ) {
233
+ LOG_ERR ("failure disabling I2C clock" );
234
+ return ret ;
235
+ }
236
+
237
+ /* Move pins to sleep state */
238
+ ret = pinctrl_apply_state (cfg -> pcfg , PINCTRL_STATE_SLEEP );
239
+ if (ret == - ENOENT ) {
240
+ /* Warn but don't block suspend */
241
+ LOG_WRN ("I2C pinctrl sleep state not available " );
242
+ } else if (ret < 0 ) {
243
+ return ret ;
244
+ }
245
+
246
+ return 0 ;
247
+ }
248
+
249
+ #endif
250
+
251
+ static int i2c_stm32_activate (const struct device * dev )
252
+ {
253
+ int ret ;
254
+ const struct i2c_stm32_config * cfg = dev -> config ;
255
+ const struct device * const clk = DEVICE_DT_GET (STM32_CLOCK_CONTROL_NODE );
256
+
257
+ /* Move pins to active/default state */
258
+ ret = pinctrl_apply_state (cfg -> pcfg , PINCTRL_STATE_DEFAULT );
259
+ if (ret < 0 ) {
260
+ LOG_ERR ("I2C pinctrl setup failed (%d)" , ret );
261
+ return ret ;
262
+ }
263
+
264
+ /* Enable device clock. */
265
+ if (clock_control_on (clk ,
266
+ (clock_control_subsys_t * ) & cfg -> pclken [0 ]) != 0 ) {
267
+ LOG_ERR ("i2c: failure enabling clock" );
268
+ return - EIO ;
269
+ }
270
+
271
+ return 0 ;
272
+ }
273
+
274
+
212
275
static int i2c_stm32_init (const struct device * dev )
213
276
{
214
277
const struct device * const clk = DEVICE_DT_GET (STM32_CLOCK_CONTROL_NODE );
@@ -221,13 +284,6 @@ static int i2c_stm32_init(const struct device *dev)
221
284
cfg -> irq_config_func (dev );
222
285
#endif
223
286
224
- /* Configure dt provided device signals when available */
225
- ret = pinctrl_apply_state (cfg -> pcfg , PINCTRL_STATE_DEFAULT );
226
- if (ret < 0 ) {
227
- LOG_ERR ("I2C pinctrl setup failed (%d)" , ret );
228
- return ret ;
229
- }
230
-
231
287
/*
232
288
* initialize mutex used when multiple transfers
233
289
* are taking place to guarantee that each one is
@@ -240,11 +296,7 @@ static int i2c_stm32_init(const struct device *dev)
240
296
return - ENODEV ;
241
297
}
242
298
243
- if (clock_control_on (clk ,
244
- (clock_control_subsys_t * ) & cfg -> pclken [0 ]) != 0 ) {
245
- LOG_ERR ("i2c: failure enabling clock" );
246
- return - EIO ;
247
- }
299
+ i2c_stm32_activate (dev );
248
300
249
301
if (IS_ENABLED (STM32_I2C_DOMAIN_CLOCK_SUPPORT ) && (cfg -> pclk_len > 1 )) {
250
302
/* Enable I2C clock source */
@@ -279,6 +331,28 @@ static int i2c_stm32_init(const struct device *dev)
279
331
return 0 ;
280
332
}
281
333
334
+ #ifdef CONFIG_PM_DEVICE
335
+
336
+ static int i2c_stm32_pm_action (const struct device * dev , enum pm_device_action action )
337
+ {
338
+ int err ;
339
+
340
+ switch (action ) {
341
+ case PM_DEVICE_ACTION_RESUME :
342
+ err = i2c_stm32_activate (dev );
343
+ break ;
344
+ case PM_DEVICE_ACTION_SUSPEND :
345
+ err = i2c_stm32_suspend (dev );
346
+ break ;
347
+ default :
348
+ return - ENOTSUP ;
349
+ }
350
+
351
+ return err ;
352
+ }
353
+
354
+ #endif
355
+
282
356
/* Macros for I2C instance declaration */
283
357
284
358
#ifdef CONFIG_I2C_STM32_INTERRUPT
@@ -360,8 +434,11 @@ static const struct i2c_stm32_config i2c_stm32_cfg_##index = { \
360
434
\
361
435
static struct i2c_stm32_data i2c_stm32_dev_data_##index; \
362
436
\
437
+ PM_DEVICE_DT_INST_DEFINE(index, i2c_stm32_pm_action); \
438
+ \
363
439
I2C_DEVICE_DT_INST_DEFINE(index, i2c_stm32_init, \
364
- NULL, &i2c_stm32_dev_data_##index, \
440
+ PM_DEVICE_DT_INST_GET(index), \
441
+ &i2c_stm32_dev_data_##index, \
365
442
&i2c_stm32_cfg_##index, \
366
443
POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \
367
444
&api_funcs); \
0 commit comments