Skip to content

Commit 295a3b6

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 c3fca45 commit 295a3b6

File tree

1 file changed

+185
-189
lines changed

1 file changed

+185
-189
lines changed

drivers/dac/dac_mcux_gau.c

Lines changed: 185 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -1,194 +1,190 @@
11
/*
2-
* Copyright 2023 NXP
3-
*
4-
* SPDX-License-Identifier: Apache-2.0
5-
*/
6-
7-
#define DT_DRV_COMPAT nxp_gau_dac
8-
9-
#include <zephyr/drivers/dac.h>
10-
11-
#include <fsl_dac.h>
12-
#include "fsl_clock.h"
13-
#define LOG_LEVEL CONFIG_DAC_LOG_LEVEL
14-
#include <zephyr/logging/log.h>
15-
#include <zephyr/irq.h>
16-
#include <zephyr/pm/policy.h>
17-
#include <zephyr/pm/device.h>
18-
LOG_MODULE_REGISTER(nxp_gau_dac);
19-
20-
#define ZEPHYR_USER_NODE_RESTORE DT_PATH(zephyr_user)
21-
#if (DT_NODE_HAS_PROP(ZEPHYR_USER_NODE_RESTORE, dac) && \
22-
DT_NODE_HAS_PROP(ZEPHYR_USER_NODE_RESTORE, dac_channel_id) && \
23-
DT_NODE_HAS_PROP(ZEPHYR_USER_NODE_RESTORE, dac_resolution))
24-
#define DAC_NODE DT_PHANDLE(ZEPHYR_USER_NODE_RESTORE, dac)
25-
#define DAC_CHANNEL_ID_RESTORE DT_PROP(ZEPHYR_USER_NODE_RESTORE, dac_channel_id)
26-
#define DAC_RESOLUTION_RESTORE DT_PROP(ZEPHYR_USER_NODE_RESTORE, dac_resolution)
27-
#endif
28-
29-
struct nxp_gau_dac_config {
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;
2+
* Copyright 2023 NXP
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT nxp_gau_dac
8+
#include <zephyr/drivers/dac.h>
9+
10+
#include <fsl_dac.h>
11+
#include "fsl_clock.h"
12+
#define LOG_LEVEL CONFIG_DAC_LOG_LEVEL
13+
#include <zephyr/logging/log.h>
14+
#include <zephyr/irq.h>
15+
#include <zephyr/pm/policy.h>
16+
#include <zephyr/pm/device.h>
17+
LOG_MODULE_REGISTER(nxp_gau_dac);
18+
19+
#define ZEPHYR_USER_NODE_RESTORE DT_PATH(zephyr_user)
20+
#if (DT_NODE_HAS_PROP(ZEPHYR_USER_NODE_RESTORE, dac) && \
21+
DT_NODE_HAS_PROP(ZEPHYR_USER_NODE_RESTORE, dac_channel_id) && \
22+
DT_NODE_HAS_PROP(ZEPHYR_USER_NODE_RESTORE, dac_resolution))
23+
#define DAC_NODE DT_PHANDLE(ZEPHYR_USER_NODE_RESTORE, dac)
24+
#define DAC_CHANNEL_ID_RESTORE DT_PROP(ZEPHYR_USER_NODE_RESTORE, dac_channel_id)
25+
#define DAC_RESOLUTION_RESTORE DT_PROP(ZEPHYR_USER_NODE_RESTORE, dac_resolution)
26+
#endif
27+
28+
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;
33+
};
34+
35+
static inline dac_channel_id_t convert_channel_id(uint8_t channel_id)
36+
{
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;
3443
};
35-
36-
static inline dac_channel_id_t convert_channel_id(uint8_t channel_id)
37-
{
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-
};
44+
}
45+
46+
static int nxp_gau_dac_channel_setup(const struct device *dev,
47+
const struct dac_channel_cfg *channel_cfg)
48+
{
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;
4559
}
46-
47-
static int nxp_gau_dac_channel_setup(const struct device *dev,
48-
const struct dac_channel_cfg *channel_cfg)
49-
{
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;
86-
};
87-
88-
static int nxp_gau_dac_write_value(const struct device *dev,
89-
uint8_t channel, uint32_t value)
90-
{
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;
97-
};
98-
99-
static DEVICE_API(dac, nxp_gau_dac_driver_api) = {
100-
.channel_setup = nxp_gau_dac_channel_setup,
101-
.write_value = nxp_gau_dac_write_value,
102-
};
103-
104-
static int nxp_gau_dac_init(const struct device *dev)
105-
{
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;
117-
};
118-
119-
static int nxp_gau_dac_init_common(const struct device *dev)
120-
{
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;
141-
};
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;
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;
15168
}
152-
153-
static int dac_mcux_pm_action(const struct device *dev, enum pm_device_action action)
154-
{ static const struct dac_channel_cfg dac_ch_cfg_pm = {
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;
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;
84+
};
85+
86+
static int nxp_gau_dac_write_value(const struct device *dev,
87+
uint8_t channel, uint32_t value)
88+
{
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;
95+
};
96+
97+
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+
};
101+
102+
static int nxp_gau_dac_init(const struct device *dev)
103+
{
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;
115+
};
116+
117+
static int nxp_gau_dac_init_common(const struct device *dev)
118+
{
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;
138+
};
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;
148+
}
149+
150+
static int dac_mcux_pm_action(const struct device *dev, enum pm_device_action action)
151+
{ 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;
174169
}
175-
176-
#define NXP_GAU_DAC_INIT(inst) \
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-
193-
DT_INST_FOREACH_STATUS_OKAY(NXP_GAU_DAC_INIT)
194-
170+
return 0;
171+
}
172+
173+
#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+
190+
DT_INST_FOREACH_STATUS_OKAY(NXP_GAU_DAC_INIT)

0 commit comments

Comments
 (0)