@@ -839,6 +839,10 @@ static int spi_stm32_init(const struct device *dev)
839839 return err ;
840840 }
841841
842+ #ifdef CONFIG_PM_DEVICE
843+ data -> pm_state = PM_DEVICE_STATE_ACTIVE ;
844+ #endif
845+
842846#ifdef CONFIG_SPI_STM32_INTERRUPT
843847 cfg -> irq_config (dev );
844848#endif
@@ -861,6 +865,76 @@ static int spi_stm32_init(const struct device *dev)
861865 return 0 ;
862866}
863867
868+ #ifdef CONFIG_PM_DEVICE
869+ static int spi_stm32_set_power_state (const struct device * dev ,
870+ uint32_t new_state )
871+ {
872+ const struct spi_stm32_config * cfg = DEV_CFG (dev );
873+ struct spi_stm32_data * data = DEV_DATA (dev );
874+ SPI_TypeDef * spi = cfg -> spi ;
875+
876+ /* setting a low power mode */
877+ if (new_state != PM_DEVICE_STATE_ACTIVE ) {
878+ #ifdef SPI_SR_FTLVL
879+ /* 1. Wait until FTLVL[1:0] = 00 (no more data to transmit) */
880+ while (LL_SPI_GetTxFIFOLevel (spi ) > 0 ) {
881+ }
882+ #endif
883+ /* 2. Wait until BSY=0 (the last data frame is processed) */
884+ while (ll_func_spi_is_busy (spi )) {
885+ /* NOP */
886+ }
887+ /* 3. Disable the SPI (SPE=0) */
888+ LL_SPI_Disable (spi );
889+ #ifdef SPI_SR_FRLVL
890+ /* 4. Read data until FRLVL[1:0] = 00 (read all the received data)
891+ * We wait until all data is read */
892+ while (LL_SPI_GetRxFIFOLevel (spi ) > 0 ) {
893+ }
894+ #endif
895+ } else if (new_state == PM_DEVICE_STATE_ACTIVE ) {
896+ LL_SPI_Enable (spi );
897+ }
898+ data -> pm_state = new_state ;
899+ /* UartInstance returning to active mode has nothing special to do */
900+ return 0 ;
901+ }
902+
903+ /**
904+ * @brief disable the UART channel
905+ *
906+ * This routine is called to put the device in low power mode.
907+ *
908+ * @param dev UART device struct
909+ *
910+ * @return 0
911+ */
912+ static int spi_stm32_pm_control (const struct device * dev ,
913+ uint32_t ctrl_command ,
914+ uint32_t * state , pm_device_cb cb ,
915+ void * arg )
916+ {
917+ struct spi_stm32_data * data = DEV_DATA (dev );
918+
919+ if (ctrl_command == PM_DEVICE_STATE_SET ) {
920+ uint32_t new_state = * state ;
921+
922+ if (new_state != data -> pm_state ) {
923+ spi_stm32_set_power_state (dev , new_state );
924+ }
925+ } else {
926+ __ASSERT_NO_MSG (ctrl_command == PM_DEVICE_STATE_GET );
927+ * state = data -> pm_state ;
928+ }
929+
930+ if (cb ) {
931+ cb (dev , 0 , state , arg );
932+ }
933+
934+ return 0 ;
935+ }
936+ #endif /* CONFIG_PM_DEVICE */
937+
864938#ifdef CONFIG_SPI_STM32_INTERRUPT
865939#define STM32_SPI_IRQ_HANDLER_DECL (id ) \
866940 static void spi_stm32_irq_config_func_##id(const struct device *dev)
@@ -955,7 +1029,7 @@ static struct spi_stm32_data spi_stm32_dev_data_##id = { \
9551029 SPI_DMA_STATUS_SEM(id) \
9561030}; \
9571031 \
958- DEVICE_DT_INST_DEFINE(id, &spi_stm32_init, NULL, \
1032+ DEVICE_DT_INST_DEFINE(id, &spi_stm32_init, &spi_stm32_pm_control, \
9591033 &spi_stm32_dev_data_##id, &spi_stm32_cfg_##id, \
9601034 POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \
9611035 &api_funcs); \
0 commit comments