Skip to content

Commit 16e180a

Browse files
committed
drivers: actuator: dac_mcux_gau: Add PM3 support
Added PM3 support to the rw61x in the dac driver Signed-off-by: JairGudino <ramonjair.gudino@nxp.com>
1 parent 295a3b6 commit 16e180a

File tree

1 file changed

+149
-145
lines changed

1 file changed

+149
-145
lines changed

drivers/dac/dac_mcux_gau.c

Lines changed: 149 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/*
2-
* Copyright 2023 NXP
3-
*
4-
* SPDX-License-Identifier: Apache-2.0
5-
*/
2+
* Copyright 2023 NXP
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
66

77
#define DT_DRV_COMPAT nxp_gau_dac
8-
#include <zephyr/drivers/dac.h>
98

9+
#include <zephyr/drivers/dac.h>
10+
1011
#include <fsl_dac.h>
1112
#include "fsl_clock.h"
1213
#define LOG_LEVEL CONFIG_DAC_LOG_LEVEL
@@ -15,7 +16,7 @@
1516
#include <zephyr/pm/policy.h>
1617
#include <zephyr/pm/device.h>
1718
LOG_MODULE_REGISTER(nxp_gau_dac);
18-
19+
1920
#define ZEPHYR_USER_NODE_RESTORE DT_PATH(zephyr_user)
2021
#if (DT_NODE_HAS_PROP(ZEPHYR_USER_NODE_RESTORE, dac) && \
2122
DT_NODE_HAS_PROP(ZEPHYR_USER_NODE_RESTORE, dac_channel_id) && \
@@ -24,167 +25,170 @@ DT_NODE_HAS_PROP(ZEPHYR_USER_NODE_RESTORE, dac_resolution))
2425
#define DAC_CHANNEL_ID_RESTORE DT_PROP(ZEPHYR_USER_NODE_RESTORE, dac_channel_id)
2526
#define DAC_RESOLUTION_RESTORE DT_PROP(ZEPHYR_USER_NODE_RESTORE, dac_resolution)
2627
#endif
27-
28+
2829
struct nxp_gau_dac_config {
29-
DAC_Type *base;
30-
dac_conversion_rate_t conversion_rate : 2;
31-
dac_reference_voltage_source_t voltage_ref : 1;
32-
dac_output_voltage_range_t output_range : 2;
30+
DAC_Type *base;
31+
dac_conversion_rate_t conversion_rate : 2;
32+
dac_reference_voltage_source_t voltage_ref : 1;
33+
dac_output_voltage_range_t output_range : 2;
3334
};
34-
35+
3536
static inline dac_channel_id_t convert_channel_id(uint8_t channel_id)
3637
{
37-
switch (channel_id) {
38-
case 0: return kDAC_ChannelA;
39-
case 1: return kDAC_ChannelB;
40-
default:
41-
LOG_ERR("Invalid DAC channel ID");
42-
return -EINVAL;
43-
};
38+
switch (channel_id) {
39+
case 0: return kDAC_ChannelA;
40+
case 1: return kDAC_ChannelB;
41+
default:
42+
LOG_ERR("Invalid DAC channel ID");
43+
return -EINVAL;
44+
};
4445
}
45-
46+
4647
static int nxp_gau_dac_channel_setup(const struct device *dev,
47-
const struct dac_channel_cfg *channel_cfg)
48+
const struct dac_channel_cfg *channel_cfg)
4849
{
49-
const struct nxp_gau_dac_config *config = dev->config;
50-
dac_channel_config_t dac_channel_config = {0};
51-
bool use_internal = true;
52-
pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); //Lock the PM MODE 3
53-
pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); //Lock the PM MODE 2
54-
pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); //Lock the PM MODE 1
55-
56-
if (channel_cfg->resolution != 10) {
57-
LOG_ERR("DAC only support 10 bit resolution");
58-
return -EINVAL;
59-
}
60-
61-
if (channel_cfg->internal && channel_cfg->buffered) {
62-
LOG_ERR("DAC output can not be buffered and internal");
63-
return -EINVAL;
64-
} else if (channel_cfg->buffered) {
65-
/* External and internal output are mutually exclusive */
66-
LOG_WRN("Note: buffering DAC output to pad disconnects internal output");
67-
use_internal = false;
68-
}
69-
70-
dac_channel_config.waveType = kDAC_WaveNormal;
71-
dac_channel_config.outMode =
72-
use_internal ? kDAC_ChannelOutputInternal : kDAC_ChannelOutputPAD;
73-
dac_channel_config.timingMode = kDAC_NonTimingCorrelated;
74-
dac_channel_config.enableTrigger = false;
75-
dac_channel_config.enableDMA = false;
76-
dac_channel_config.enableConversion = true;
77-
78-
79-
DAC_SetChannelConfig(config->base,
80-
(uint32_t)convert_channel_id(channel_cfg->channel_id),
81-
&dac_channel_config);
82-
83-
return 0;
50+
const struct nxp_gau_dac_config *config = dev->config;
51+
dac_channel_config_t dac_channel_config = {0};
52+
bool use_internal = true;
53+
54+
pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); //Lock the PM MODE 3
55+
pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); //Lock the PM MODE 2
56+
pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); //Lock the PM MODE 1
57+
58+
if (channel_cfg->resolution != 10) {
59+
LOG_ERR("DAC only support 10 bit resolution");
60+
return -EINVAL;
61+
}
62+
63+
if (channel_cfg->internal && channel_cfg->buffered) {
64+
LOG_ERR("DAC output can not be buffered and internal");
65+
return -EINVAL;
66+
} else if (channel_cfg->buffered) {
67+
/* External and internal output are mutually exclusive */
68+
LOG_WRN("Note: buffering DAC output to pad disconnects internal output");
69+
use_internal = false;
70+
}
71+
72+
dac_channel_config.waveType = kDAC_WaveNormal;
73+
dac_channel_config.outMode =
74+
use_internal ? kDAC_ChannelOutputInternal : kDAC_ChannelOutputPAD;
75+
dac_channel_config.timingMode = kDAC_NonTimingCorrelated;
76+
dac_channel_config.enableTrigger = false;
77+
dac_channel_config.enableDMA = false;
78+
dac_channel_config.enableConversion = true;
79+
80+
81+
DAC_SetChannelConfig(config->base,
82+
(uint32_t)convert_channel_id(channel_cfg->channel_id),
83+
&dac_channel_config);
84+
85+
return 0;
8486
};
85-
87+
8688
static int nxp_gau_dac_write_value(const struct device *dev,
87-
uint8_t channel, uint32_t value)
89+
uint8_t channel, uint32_t value)
8890
{
89-
const struct nxp_gau_dac_config *config = dev->config;
90-
91-
DAC_SetChannelData(config->base,
92-
(uint32_t)convert_channel_id(channel),
93-
(uint16_t)value);
94-
return 0;
91+
const struct nxp_gau_dac_config *config = dev->config;
92+
93+
DAC_SetChannelData(config->base,
94+
(uint32_t)convert_channel_id(channel),
95+
(uint16_t)value);
96+
return 0;
9597
};
96-
98+
9799
static DEVICE_API(dac, nxp_gau_dac_driver_api) = {
98-
.channel_setup = nxp_gau_dac_channel_setup,
99-
.write_value = nxp_gau_dac_write_value,
100+
.channel_setup = nxp_gau_dac_channel_setup,
101+
.write_value = nxp_gau_dac_write_value,
100102
};
101-
103+
102104
static int nxp_gau_dac_init(const struct device *dev)
103105
{
104-
const struct nxp_gau_dac_config *config = dev->config;
105-
dac_config_t dac_cfg;
106-
DAC_GetDefaultConfig(&dac_cfg);
107-
108-
dac_cfg.conversionRate = config->conversion_rate;
109-
dac_cfg.refSource = config->voltage_ref;
110-
dac_cfg.rangeSelect = config->output_range;
111-
112-
DAC_Init(config->base, &dac_cfg);
113-
114-
return 0;
106+
const struct nxp_gau_dac_config *config = dev->config;
107+
dac_config_t dac_cfg;
108+
DAC_GetDefaultConfig(&dac_cfg);
109+
110+
dac_cfg.conversionRate = config->conversion_rate;
111+
dac_cfg.refSource = config->voltage_ref;
112+
dac_cfg.rangeSelect = config->output_range;
113+
114+
DAC_Init(config->base, &dac_cfg);
115+
116+
return 0;
115117
};
116-
118+
117119
static int nxp_gau_dac_init_common(const struct device *dev)
118120
{
119-
const struct nxp_gau_dac_config *config = dev->config;
120-
dac_config_t dac_cfg;
121-
DAC_GetDefaultConfig(&dac_cfg);
122-
123-
dac_cfg.conversionRate = config->conversion_rate;
124-
dac_cfg.refSource = config->voltage_ref;
125-
dac_cfg.rangeSelect = config->output_range;
126-
127-
DAC_Init(config->base, &dac_cfg);
128-
129-
/* Attack clock for GAU and reset */
130-
CLOCK_AttachClk(kMAIN_CLK_to_GAU_CLK);
131-
CLOCK_SetClkDiv(kCLOCK_DivGauClk, 1U);
132-
CLOCK_EnableClock(kCLOCK_Gau);
133-
RESET_PeripheralReset(kGAU_RST_SHIFT_RSTn);
134-
135-
POWER_PowerOnGau();
136-
137-
return 0;
121+
const struct nxp_gau_dac_config *config = dev->config;
122+
dac_config_t dac_cfg;
123+
124+
DAC_GetDefaultConfig(&dac_cfg);
125+
126+
dac_cfg.conversionRate = config->conversion_rate;
127+
dac_cfg.refSource = config->voltage_ref;
128+
dac_cfg.rangeSelect = config->output_range;
129+
130+
DAC_Init(config->base, &dac_cfg);
131+
132+
/* Attack clock for GAU and reset */
133+
CLOCK_AttachClk(kMAIN_CLK_to_GAU_CLK);
134+
CLOCK_SetClkDiv(kCLOCK_DivGauClk, 1U);
135+
CLOCK_EnableClock(kCLOCK_Gau);
136+
RESET_PeripheralReset(kGAU_RST_SHIFT_RSTn);
137+
138+
POWER_PowerOnGau();
139+
140+
return 0;
138141
};
139-
140-
int nxp_gau_deinit(const struct device *dev){
141-
const struct nxp_gau_dac_config *config = dev->config;
142-
DAC_Deinit(config->base);
143-
144-
pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); //Lock the PM MODE 3
145-
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); //Lock the PM MODE 2
146-
pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); //Lock the PM MODE 1
147-
return 0;
142+
143+
int nxp_gau_deinit(const struct device *dev){
144+
const struct nxp_gau_dac_config *config = dev->config;
145+
DAC_Deinit(config->base);
146+
147+
pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); //Lock the PM MODE 3
148+
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); //Lock the PM MODE 2
149+
pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); //Lock the PM MODE 1
150+
return 0;
148151
}
149-
152+
150153
static int dac_mcux_pm_action(const struct device *dev, enum pm_device_action action)
151154
{ static const struct dac_channel_cfg dac_ch_cfg_pm = {
152-
.channel_id = DAC_CHANNEL_ID_RESTORE,
153-
.resolution = DAC_RESOLUTION_RESTORE,
154-
.buffered = true
155-
};
156-
157-
switch (action) {
158-
case PM_DEVICE_ACTION_RESUME:
159-
break;
160-
case PM_DEVICE_ACTION_SUSPEND:
161-
break;
162-
case PM_DEVICE_ACTION_TURN_OFF:
163-
break;
164-
case PM_DEVICE_ACTION_TURN_ON:
165-
nxp_gau_dac_init_common(dev);
166-
break;
167-
default:
168-
return -ENOTSUP;
169-
}
170-
return 0;
155+
.channel_id = DAC_CHANNEL_ID_RESTORE,
156+
.resolution = DAC_RESOLUTION_RESTORE,
157+
.buffered = true
158+
};
159+
160+
switch (action) {
161+
case PM_DEVICE_ACTION_RESUME:
162+
break;
163+
case PM_DEVICE_ACTION_SUSPEND:
164+
break;
165+
case PM_DEVICE_ACTION_TURN_OFF:
166+
break;
167+
case PM_DEVICE_ACTION_TURN_ON:
168+
nxp_gau_dac_init_common(dev);
169+
break;
170+
default:
171+
return -ENOTSUP;
172+
}
173+
return 0;
171174
}
172-
175+
173176
#define NXP_GAU_DAC_INIT(inst) \
174-
\
175-
const struct nxp_gau_dac_config nxp_gau_dac_##inst##_config = { \
176-
.base = (DAC_Type *) DT_INST_REG_ADDR(inst), \
177-
.voltage_ref = DT_INST_ENUM_IDX(inst, nxp_dac_reference), \
178-
.conversion_rate = DT_INST_ENUM_IDX(inst, nxp_conversion_rate), \
179-
.output_range = DT_INST_ENUM_IDX(inst, \
180-
nxp_output_voltage_range), \
181-
}; \
182-
PM_DEVICE_DT_INST_DEFINE(inst, dac_mcux_pm_action); \
183-
\
184-
DEVICE_DT_INST_DEFINE(inst, &nxp_gau_dac_init, PM_DEVICE_DT_INST_GET(inst), \
185-
NULL, \
186-
&nxp_gau_dac_##inst##_config, \
187-
POST_KERNEL, CONFIG_DAC_INIT_PRIORITY, \
188-
&nxp_gau_dac_driver_api);
189-
177+
\
178+
const struct nxp_gau_dac_config nxp_gau_dac_##inst##_config = { \
179+
.base = (DAC_Type *) DT_INST_REG_ADDR(inst), \
180+
.voltage_ref = DT_INST_ENUM_IDX(inst, nxp_dac_reference), \
181+
.conversion_rate = DT_INST_ENUM_IDX(inst, nxp_conversion_rate), \
182+
.output_range = DT_INST_ENUM_IDX(inst, \
183+
nxp_output_voltage_range), \
184+
}; \
185+
PM_DEVICE_DT_INST_DEFINE(inst, dac_mcux_pm_action); \
186+
\
187+
DEVICE_DT_INST_DEFINE(inst, &nxp_gau_dac_init, PM_DEVICE_DT_INST_GET(inst), \
188+
NULL, \
189+
&nxp_gau_dac_##inst##_config, \
190+
POST_KERNEL, CONFIG_DAC_INIT_PRIORITY, \
191+
&nxp_gau_dac_driver_api);
192+
190193
DT_INST_FOREACH_STATUS_OKAY(NXP_GAU_DAC_INIT)
194+

0 commit comments

Comments
 (0)