Skip to content

Commit bfe2fa5

Browse files
FelixWang47831Hardevsinh-Palaniya
authored andcommitted
drivers: Counter: TPM improvement
1.Include barrier.h to fix barrier_dsync_fence_full() not found issue 2.Support multiple channels for alarm function Signed-off-by: Felix Wang <fei.wang_3@nxp.com>
1 parent 99fb3fd commit bfe2fa5

File tree

1 file changed

+43
-25
lines changed

1 file changed

+43
-25
lines changed

drivers/counter/counter_mcux_tpm.c

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@
1010
#include <zephyr/drivers/clock_control.h>
1111
#include <zephyr/irq.h>
1212
#include <zephyr/logging/log.h>
13+
#include <zephyr/sys/barrier.h>
1314

1415
#include <fsl_tpm.h>
1516

1617
LOG_MODULE_REGISTER(mcux_tpm, CONFIG_COUNTER_LOG_LEVEL);
1718

19+
struct mcux_tpm_channel_data {
20+
counter_alarm_callback_t alarm_callback;
21+
void *alarm_user_data;
22+
};
23+
1824
#define DEV_CFG(_dev) ((const struct mcux_tpm_config *)(_dev)->config)
1925
#define DEV_DATA(_dev) ((struct mcux_tpm_data *)(_dev)->data)
2026

@@ -33,10 +39,9 @@ struct mcux_tpm_config {
3339

3440
struct mcux_tpm_data {
3541
DEVICE_MMIO_NAMED_RAM(tpm_mmio);
36-
counter_alarm_callback_t alarm_callback;
3742
counter_top_callback_t top_callback;
3843
uint32_t freq;
39-
void *alarm_user_data;
44+
struct mcux_tpm_channel_data channels[TPM_CONTROLS_COUNT];
4045
void *top_user_data;
4146
};
4247

@@ -82,11 +87,16 @@ static int mcux_tpm_set_alarm(const struct device *dev, uint8_t chan_id,
8287
struct mcux_tpm_data *data = dev->data;
8388
uint32_t ticks = alarm_cfg->ticks;
8489

85-
if (chan_id != kTPM_Chnl_0) {
90+
if (chan_id >= DEV_CFG(dev)->info.channels) {
8691
LOG_ERR("Invalid channel id");
8792
return -EINVAL;
8893
}
8994

95+
if (data->channels[chan_id].alarm_callback != NULL) {
96+
LOG_ERR("channel already in use");
97+
return -EBUSY;
98+
}
99+
90100
if (ticks > (top_value)) {
91101
return -EINVAL;
92102
}
@@ -99,15 +109,11 @@ static int mcux_tpm_set_alarm(const struct device *dev, uint8_t chan_id,
99109
}
100110
}
101111

102-
if (data->alarm_callback) {
103-
return -EBUSY;
104-
}
112+
data->channels[chan_id].alarm_callback = alarm_cfg->callback;
113+
data->channels[chan_id].alarm_user_data = alarm_cfg->user_data;
105114

106-
data->alarm_callback = alarm_cfg->callback;
107-
data->alarm_user_data = alarm_cfg->user_data;
108-
109-
TPM_SetupOutputCompare(base, kTPM_Chnl_0, kTPM_NoOutputSignal, ticks);
110-
TPM_EnableInterrupts(base, kTPM_Chnl0InterruptEnable);
115+
TPM_SetupOutputCompare(base, chan_id, kTPM_NoOutputSignal, ticks);
116+
TPM_EnableInterrupts(base, BIT(chan_id));
111117

112118
return 0;
113119
}
@@ -117,13 +123,14 @@ static int mcux_tpm_cancel_alarm(const struct device *dev, uint8_t chan_id)
117123
TPM_Type *base = get_base(dev);
118124
struct mcux_tpm_data *data = dev->data;
119125

120-
if (chan_id != kTPM_Chnl_0) {
126+
if (chan_id >= DEV_CFG(dev)->info.channels) {
121127
LOG_ERR("Invalid channel id");
122128
return -EINVAL;
123129
}
124130

125-
TPM_DisableInterrupts(base, kTPM_Chnl0InterruptEnable);
126-
data->alarm_callback = NULL;
131+
TPM_DisableInterrupts(base, BIT(chan_id));
132+
data->channels[chan_id].alarm_callback = NULL;
133+
data->channels[chan_id].alarm_user_data = NULL;
127134

128135
return 0;
129136
}
@@ -135,17 +142,20 @@ void mcux_tpm_isr(const struct device *dev)
135142
uint32_t current = TPM_GetCurrentTimerCount(base);
136143
uint32_t status;
137144

138-
status = TPM_GetStatusFlags(base) & (kTPM_Chnl0Flag | kTPM_TimeOverflowFlag);
145+
status = TPM_GetStatusFlags(base);
139146
TPM_ClearStatusFlags(base, status);
140147
barrier_dsync_fence_full();
141148

142-
if ((status & kTPM_Chnl0Flag) && data->alarm_callback) {
143-
TPM_DisableInterrupts(base,
144-
kTPM_Chnl0InterruptEnable);
145-
counter_alarm_callback_t alarm_cb = data->alarm_callback;
149+
for (uint8_t chan = 0; chan < DEV_CFG(dev)->info.channels; chan++) {
150+
if ((status & BIT(chan)) != 0 && (data->channels[chan].alarm_callback != NULL)) {
151+
counter_alarm_callback_t alarm_callback =
152+
data->channels[chan].alarm_callback;
153+
void *alarm_user_data = data->channels[chan].alarm_user_data;
146154

147-
data->alarm_callback = NULL;
148-
alarm_cb(dev, 0, current, data->alarm_user_data);
155+
data->channels[chan].alarm_callback = NULL;
156+
data->channels[chan].alarm_user_data = NULL;
157+
alarm_callback(dev, chan, current, alarm_user_data);
158+
}
149159
}
150160

151161
if ((status & kTPM_TimeOverflowFlag) && data->top_callback) {
@@ -157,7 +167,7 @@ static uint32_t mcux_tpm_get_pending_int(const struct device *dev)
157167
{
158168
TPM_Type *base = get_base(dev);
159169

160-
return (TPM_GetStatusFlags(base) & kTPM_Chnl0Flag);
170+
return TPM_GetStatusFlags(base) ? 1 : 0;
161171
}
162172

163173
static int mcux_tpm_set_top_value(const struct device *dev,
@@ -167,8 +177,10 @@ static int mcux_tpm_set_top_value(const struct device *dev,
167177
TPM_Type *base = get_base(dev);
168178
struct mcux_tpm_data *data = dev->data;
169179

170-
if (data->alarm_callback) {
171-
return -EBUSY;
180+
for (uint8_t chan = 0; chan < config->info.channels; chan++) {
181+
if (data->channels[chan].alarm_callback) {
182+
return -EBUSY;
183+
}
172184
}
173185

174186
/* Check if timer already enabled. */
@@ -228,6 +240,11 @@ static int mcux_tpm_init(const struct device *dev)
228240
return -ENODEV;
229241
}
230242

243+
for (uint8_t chan = 0; chan < DEV_CFG(dev)->info.channels; chan++) {
244+
data->channels[chan].alarm_callback = NULL;
245+
data->channels[chan].alarm_user_data = NULL;
246+
}
247+
231248
if (clock_control_on(config->clock_dev, config->clock_subsys)) {
232249
LOG_ERR("Could not turn on clock");
233250
return -EINVAL;
@@ -282,7 +299,8 @@ static DEVICE_API(counter, mcux_tpm_driver_api) = {
282299
.info = { \
283300
.max_top_value = TPM_MAX_COUNTER_VALUE(TPM(n)), \
284301
.freq = 0, \
285-
.channels = 1, \
302+
.channels = FSL_FEATURE_TPM_CHANNEL_COUNTn( \
303+
(TPM_Type *)DT_INST_REG_ADDR(n)), \
286304
.flags = COUNTER_CONFIG_INFO_COUNT_UP, \
287305
}, \
288306
.irq_config_func = mcux_tpm_irq_config_ ## n, \

0 commit comments

Comments
 (0)