1
1
/*
2
- * Copyright 2024 NXP
2
+ * Copyright 2024-2025 NXP
3
3
*
4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*/
6
6
7
+ #include <zephyr/pm/device_runtime.h>
8
+ #include <zephyr/pm/device.h>
9
+
7
10
#include "esai.h"
8
11
9
12
/* TODO:
@@ -654,14 +657,12 @@ static const struct dai_properties
654
657
655
658
static int esai_probe (const struct device * dev )
656
659
{
657
- /* nothing to be done here but mandatory to implement */
658
- return 0 ;
660
+ return pm_device_runtime_get (dev );
659
661
}
660
662
661
663
static int esai_remove (const struct device * dev )
662
664
{
663
- /* nothing to be done here but mandatory to implement */
664
- return 0 ;
665
+ return pm_device_runtime_put (dev );
665
666
}
666
667
667
668
static DEVICE_API (dai , esai_api ) = {
@@ -673,6 +674,54 @@ static DEVICE_API(dai, esai_api) = {
673
674
.remove = esai_remove ,
674
675
};
675
676
677
+ static int esai_clks_enable_disable (const struct device * dev , bool enable )
678
+ {
679
+ const struct esai_config * cfg ;
680
+ void * clk_id ;
681
+ int i , ret ;
682
+
683
+ cfg = dev -> config ;
684
+
685
+ for (i = 0 ; i < cfg -> clk_data .clock_num ; i ++ ) {
686
+ clk_id = UINT_TO_POINTER (cfg -> clk_data .clocks [i ]);
687
+
688
+ if (enable ) {
689
+ ret = clock_control_on (cfg -> clk_data .dev , clk_id );
690
+ } else {
691
+ ret = clock_control_off (cfg -> clk_data .dev , clk_id );
692
+ }
693
+
694
+ if (ret < 0 ) {
695
+ LOG_ERR ("failed to gate/ungate clock %u: %d" ,
696
+ cfg -> clk_data .clocks [i ], ret );
697
+ return ret ;
698
+ }
699
+ }
700
+
701
+ return 0 ;
702
+ }
703
+
704
+ __maybe_unused static int esai_pm_action (const struct device * dev ,
705
+ enum pm_device_action action )
706
+ {
707
+ bool enable = true;
708
+
709
+ switch (action ) {
710
+ case PM_DEVICE_ACTION_RESUME :
711
+ break ;
712
+ case PM_DEVICE_ACTION_SUSPEND :
713
+ enable = false;
714
+ break ;
715
+ case PM_DEVICE_ACTION_TURN_ON :
716
+ case PM_DEVICE_ACTION_TURN_OFF :
717
+ return 0 ;
718
+ default :
719
+ return - ENOTSUP ;
720
+ }
721
+
722
+ return esai_clks_enable_disable (dev , enable );
723
+ }
724
+
676
725
static int esai_init (const struct device * dev )
677
726
{
678
727
const struct esai_config * cfg ;
@@ -684,12 +733,19 @@ static int esai_init(const struct device *dev)
684
733
685
734
device_map (& data -> regmap , cfg -> regmap_phys , cfg -> regmap_size , K_MEM_CACHE_NONE );
686
735
736
+ #ifndef CONFIG_PM_DEVICE_RUNTIME
737
+ ret = esai_clks_enable_disable (dev , true);
738
+ if (ret < 0 ) {
739
+ return ret ;
740
+ }
741
+ #endif /* CONFIG_PM_DEVICE_RUNTIME */
742
+
687
743
ret = esai_parse_pinmodes (cfg , data );
688
744
if (ret < 0 ) {
689
745
return ret ;
690
746
}
691
747
692
- return 0 ;
748
+ return pm_device_runtime_enable ( dev ) ;
693
749
}
694
750
695
751
#define ESAI_INIT (inst ) \
@@ -749,14 +805,17 @@ static struct esai_config esai_config_##inst = { \
749
805
.pinmodes_size = ARRAY_SIZE(pinmodes_##inst), \
750
806
.clock_cfg = clock_cfg_##inst, \
751
807
.clock_cfg_size = ARRAY_SIZE(clock_cfg_##inst), \
808
+ .clk_data = ESAI_CLOCK_DATA_DECLARE(inst), \
752
809
}; \
753
810
\
754
811
static struct esai_data esai_data_##inst = { \
755
812
.cfg.type = DAI_IMX_ESAI, \
756
813
.cfg.dai_index = DT_INST_PROP_OR(inst, dai_index, 0), \
757
814
}; \
758
815
\
759
- DEVICE_DT_INST_DEFINE(inst, &esai_init, NULL, \
816
+ PM_DEVICE_DT_INST_DEFINE(inst, esai_pm_action); \
817
+ \
818
+ DEVICE_DT_INST_DEFINE(inst, &esai_init, PM_DEVICE_DT_INST_GET(inst), \
760
819
&esai_data_##inst, &esai_config_##inst, \
761
820
POST_KERNEL, CONFIG_DAI_INIT_PRIORITY, \
762
821
&esai_api); \
0 commit comments