Skip to content

Commit dc62965

Browse files
committed
[nrf fromlist] drivers: pwm: pwm_nrfx: use standard instantiation
Use API for standard instantiation and replace nrfx_err_t error values with errno. Upstream PR #: 96843 Signed-off-by: Michał Bainczyk <[email protected]>
1 parent 079d803 commit dc62965

File tree

1 file changed

+92
-89
lines changed

1 file changed

+92
-89
lines changed

drivers/pwm/pwm_nrfx.c

Lines changed: 92 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
6+
7+
#define DT_DRV_COMPAT nordic_nrf_pwm
8+
69
#include <nrfx_pwm.h>
710
#include <zephyr/drivers/pwm.h>
811
#include <zephyr/pm/device.h>
@@ -30,10 +33,7 @@ LOG_MODULE_REGISTER(pwm_nrfx, CONFIG_PWM_LOG_LEVEL);
3033
#define ANOMALY_109_EGU_IRQ_CONNECT(idx)
3134
#endif
3235

33-
#define PWM(dev_idx) DT_NODELABEL(pwm##dev_idx)
34-
#define PWM_PROP(dev_idx, prop) DT_PROP(PWM(dev_idx), prop)
35-
#define PWM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(PWM(idx), prop)
36-
#define PWM_NRFX_IS_FAST(idx) NRF_DT_IS_FAST(PWM(idx))
36+
#define PWM_NRFX_IS_FAST(inst) NRF_DT_IS_FAST(DT_DRV_INST(inst))
3737

3838
#if NRF_DT_INST_ANY_IS_FAST
3939
#define PWM_NRFX_FAST_PRESENT 1
@@ -54,7 +54,6 @@ BUILD_ASSERT(!IS_ENABLED(CONFIG_PM_DEVICE_SYSTEM_MANAGED));
5454
(compare_value | (inverted ? 0 : PWM_NRFX_CH_POLARITY_MASK))
5555

5656
struct pwm_nrfx_config {
57-
nrfx_pwm_t pwm;
5857
nrfx_pwm_config_t initial_config;
5958
nrf_pwm_sequence_t seq;
6059
const struct pinctrl_dev_config *pcfg;
@@ -69,6 +68,7 @@ struct pwm_nrfx_config {
6968
};
7069

7170
struct pwm_nrfx_data {
71+
nrfx_pwm_t pwm;
7272
uint32_t period_cycles;
7373
/* Bit mask indicating channels that need the PWM generation. */
7474
uint8_t pwm_needed;
@@ -102,7 +102,7 @@ static uint16_t *seq_values_ptr_get(const struct device *dev)
102102
return (uint16_t *)config->seq.values.p_raw;
103103
}
104104

105-
static void pwm_handler(nrfx_pwm_evt_type_t event_type, void *p_context)
105+
static void pwm_handler(nrfx_pwm_event_type_t event_type, void *p_context)
106106
{
107107
ARG_UNUSED(event_type);
108108
ARG_UNUSED(p_context);
@@ -142,7 +142,7 @@ static bool pwm_period_check_and_set(const struct device *dev,
142142
data->period_cycles = period_cycles;
143143
data->prescaler = prescaler;
144144

145-
nrf_pwm_configure(config->pwm.p_reg,
145+
nrf_pwm_configure(data->pwm.p_reg,
146146
data->prescaler,
147147
config->initial_config.count_mode,
148148
(uint16_t)countertop);
@@ -157,26 +157,25 @@ static bool pwm_period_check_and_set(const struct device *dev,
157157
return false;
158158
}
159159

160-
static bool channel_psel_get(uint32_t channel, uint32_t *psel,
161-
const struct pwm_nrfx_config *config)
160+
static bool channel_psel_get(uint32_t channel, uint32_t *psel, struct pwm_nrfx_data *data)
162161
{
163-
*psel = nrf_pwm_pin_get(config->pwm.p_reg, (uint8_t)channel);
162+
*psel = nrf_pwm_pin_get(data->pwm.p_reg, (uint8_t)channel);
164163

165164
return (((*psel & PWM_PSEL_OUT_CONNECT_Msk) >> PWM_PSEL_OUT_CONNECT_Pos)
166165
== PWM_PSEL_OUT_CONNECT_Connected);
167166
}
168167

169168
static int stop_pwm(const struct device *dev)
170169
{
171-
const struct pwm_nrfx_config *config = dev->config;
170+
struct pwm_nrfx_data *data = dev->data;
172171

173172
/* Don't wait here for the peripheral to actually stop. Instead,
174-
* ensure it is stopped before starting the next playback.
175-
*/
176-
nrfx_pwm_stop(&config->pwm, false);
173+
* ensure it is stopped before starting the next playback.
174+
*/
175+
nrfx_pwm_stop(&data->pwm, false);
177176

178177
#if PWM_NRFX_USE_CLOCK_CONTROL
179-
struct pwm_nrfx_data *data = dev->data;
178+
const struct pwm_nrfx_config *config = dev->config;
180179

181180
if (data->clock_requested) {
182181
int ret = nrf_clock_control_release(config->clk_dev, &config->clk_spec);
@@ -265,7 +264,7 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
265264
if (!needs_pwm) {
266265
uint32_t psel;
267266

268-
if (channel_psel_get(channel, &psel, config)) {
267+
if (channel_psel_get(channel, &psel, data)) {
269268
uint32_t out_level = (pulse_cycles == 0) ? 0 : 1;
270269

271270
if (inverted) {
@@ -320,7 +319,7 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
320319
* and till that moment, it ignores any start requests,
321320
* so ensure here that it is stopped.
322321
*/
323-
while (!nrfx_pwm_stopped_check(&config->pwm)) {
322+
while (!nrfx_pwm_stopped_check(&data->pwm)) {
324323
}
325324
}
326325

@@ -343,7 +342,7 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
343342
data->clock_requested = true;
344343
}
345344
#endif
346-
nrfx_pwm_simple_playback(&config->pwm, &config->seq, 1,
345+
nrfx_pwm_simple_playback(&data->pwm, &config->seq, 1,
347346
NRFX_PWM_FLAG_NO_EVT_FINISHED);
348347
}
349348

@@ -368,14 +367,16 @@ static DEVICE_API(pwm, pwm_nrfx_drv_api_funcs) = {
368367
static int pwm_resume(const struct device *dev)
369368
{
370369
const struct pwm_nrfx_config *config = dev->config;
370+
struct pwm_nrfx_data *data = dev->data;
371+
371372
uint8_t initially_inverted = 0;
372373

373374
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
374375

375376
for (size_t i = 0; i < NRF_PWM_CHANNEL_COUNT; i++) {
376377
uint32_t psel;
377378

378-
if (channel_psel_get(i, &psel, config)) {
379+
if (channel_psel_get(i, &psel, data)) {
379380
/* Mark channels as inverted according to what initial
380381
* state of their outputs has been set by pinctrl (high
381382
* idle state means that the channel is inverted).
@@ -397,6 +398,7 @@ static int pwm_resume(const struct device *dev)
397398
static int pwm_suspend(const struct device *dev)
398399
{
399400
const struct pwm_nrfx_config *config = dev->config;
401+
struct pwm_nrfx_data *data = dev->data;
400402

401403
int ret = stop_pwm(dev);
402404

@@ -405,7 +407,7 @@ static int pwm_suspend(const struct device *dev)
405407
return ret;
406408
}
407409

408-
while (!nrfx_pwm_stopped_check(&config->pwm)) {
410+
while (!nrfx_pwm_stopped_check(&data->pwm)) {
409411
}
410412

411413
memset(dev->data, 0, sizeof(struct pwm_nrfx_data));
@@ -431,34 +433,36 @@ static int pwm_nrfx_pm_action(const struct device *dev,
431433
static int pwm_nrfx_init(const struct device *dev)
432434
{
433435
const struct pwm_nrfx_config *config = dev->config;
434-
nrfx_err_t err;
436+
struct pwm_nrfx_data *data = dev->data;
437+
438+
int err;
435439

436440
ANOMALY_109_EGU_IRQ_CONNECT(NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE);
437441

438442
if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
439443
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
440444
}
441445

442-
err = nrfx_pwm_init(&config->pwm, &config->initial_config, pwm_handler, dev->data);
443-
if (err != NRFX_SUCCESS) {
446+
err = nrfx_pwm_init(&data->pwm, &config->initial_config, pwm_handler, dev->data);
447+
if (err < 0) {
444448
LOG_ERR("Failed to initialize device: %s", dev->name);
445-
return -EBUSY;
449+
return err;
446450
}
447451

448452
return pm_device_driver_init(dev, pwm_nrfx_pm_action);
449453
}
450454

451-
#define PWM_MEM_REGION(idx) DT_PHANDLE(PWM(idx), memory_regions)
455+
#define PWM_MEM_REGION(inst) DT_PHANDLE(DT_DRV_INST(inst), memory_regions)
452456

453-
#define PWM_MEMORY_SECTION(idx) \
454-
COND_CODE_1(PWM_HAS_PROP(idx, memory_regions), \
457+
#define PWM_MEMORY_SECTION(inst) \
458+
COND_CODE_1(DT_NODE_HAS_PROP(inst, memory_regions), \
455459
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
456-
PWM_MEM_REGION(idx)))))), \
460+
PWM_MEM_REGION(inst)))))), \
457461
())
458462

459-
#define PWM_GET_MEM_ATTR(idx) \
460-
COND_CODE_1(PWM_HAS_PROP(idx, memory_regions), \
461-
(DT_PROP_OR(PWM_MEM_REGION(idx), zephyr_memory_attr, 0)), (0))
463+
#define PWM_GET_MEM_ATTR(inst) \
464+
COND_CODE_1(DT_NODE_HAS_PROP(inst, memory_regions), \
465+
(DT_PROP_OR(PWM_MEM_REGION(inst), zephyr_memory_attr, 0)), (0))
462466

463467
/* Fast instances depend on the global HSFLL clock controller (as they need
464468
* to request the highest frequency from it to operate correctly), so they
@@ -467,66 +471,65 @@ static int pwm_nrfx_init(const struct device *dev)
467471
*/
468472
#if defined(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY) && \
469473
CONFIG_PWM_INIT_PRIORITY < CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY
470-
#define PWM_INIT_PRIORITY(idx) \
471-
COND_CODE_1(PWM_NRFX_IS_FAST(idx), \
474+
#define PWM_INIT_PRIORITY(inst) \
475+
COND_CODE_1(PWM_NRFX_IS_FAST(inst), \
472476
(UTIL_INC(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY)), \
473477
(CONFIG_PWM_INIT_PRIORITY))
474478
#else
475-
#define PWM_INIT_PRIORITY(idx) CONFIG_PWM_INIT_PRIORITY
479+
#define PWM_INIT_PRIORITY(inst) CONFIG_PWM_INIT_PRIORITY
476480
#endif
477481

478-
#define PWM_NRFX_DEVICE(idx) \
479-
NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(PWM(idx)); \
480-
NRF_DT_CHECK_NODE_HAS_REQUIRED_MEMORY_REGIONS(PWM(idx)); \
481-
static struct pwm_nrfx_data pwm_nrfx_##idx##_data; \
482-
static uint16_t pwm_##idx##_seq_values[NRF_PWM_CHANNEL_COUNT] \
483-
PWM_MEMORY_SECTION(idx); \
484-
PINCTRL_DT_DEFINE(PWM(idx)); \
485-
static const struct pwm_nrfx_config pwm_nrfx_##idx##_config = { \
486-
.pwm = NRFX_PWM_INSTANCE(idx), \
487-
.initial_config = { \
488-
.skip_gpio_cfg = true, \
489-
.skip_psel_cfg = true, \
490-
.base_clock = NRF_PWM_CLK_1MHz, \
491-
.count_mode = (PWM_PROP(idx, center_aligned) \
492-
? NRF_PWM_MODE_UP_AND_DOWN \
493-
: NRF_PWM_MODE_UP), \
494-
.top_value = 1000, \
495-
.load_mode = NRF_PWM_LOAD_INDIVIDUAL, \
496-
.step_mode = NRF_PWM_STEP_TRIGGERED, \
497-
}, \
498-
.seq.values.p_raw = pwm_##idx##_seq_values, \
499-
.seq.length = NRF_PWM_CHANNEL_COUNT, \
500-
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(PWM(idx)), \
501-
.clock_freq = COND_CODE_1(DT_CLOCKS_HAS_IDX(PWM(idx), 0), \
502-
(DT_PROP(DT_CLOCKS_CTLR(PWM(idx)), clock_frequency)), \
503-
(16ul * 1000ul * 1000ul)), \
504-
IF_ENABLED(CONFIG_DCACHE, \
505-
(.mem_attr = PWM_GET_MEM_ATTR(idx),)) \
506-
IF_ENABLED(PWM_NRFX_USE_CLOCK_CONTROL, \
507-
(.clk_dev = PWM_NRFX_IS_FAST(idx) \
508-
? DEVICE_DT_GET(DT_CLOCKS_CTLR(PWM(idx))) \
509-
: NULL, \
510-
.clk_spec = { \
511-
.frequency = \
512-
NRF_PERIPH_GET_FREQUENCY(PWM(idx)), \
513-
},)) \
514-
}; \
515-
static int pwm_nrfx_init##idx(const struct device *dev) \
516-
{ \
517-
IRQ_CONNECT(DT_IRQN(PWM(idx)), DT_IRQ(PWM(idx), priority), \
518-
nrfx_isr, nrfx_pwm_##idx##_irq_handler, 0); \
519-
return pwm_nrfx_init(dev); \
520-
}; \
521-
PM_DEVICE_DT_DEFINE(PWM(idx), pwm_nrfx_pm_action); \
522-
DEVICE_DT_DEFINE(PWM(idx), \
523-
pwm_nrfx_init##idx, PM_DEVICE_DT_GET(PWM(idx)), \
524-
&pwm_nrfx_##idx##_data, \
525-
&pwm_nrfx_##idx##_config, \
526-
POST_KERNEL, PWM_INIT_PRIORITY(idx), \
527-
&pwm_nrfx_drv_api_funcs)
528-
529-
#define COND_PWM_NRFX_DEVICE(unused, prefix, i, _) \
530-
IF_ENABLED(CONFIG_HAS_HW_NRF_PWM##prefix##i, (PWM_NRFX_DEVICE(prefix##i);))
531-
532-
NRFX_FOREACH_PRESENT(PWM, COND_PWM_NRFX_DEVICE, (), (), _)
482+
#define PWM_NRFX_DEFINE(inst) \
483+
NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(DT_DRV_INST(inst)); \
484+
NRF_DT_CHECK_NODE_HAS_REQUIRED_MEMORY_REGIONS(DT_DRV_INST(inst)); \
485+
static struct pwm_nrfx_data pwm_nrfx_##inst##_data = { \
486+
.pwm = NRFX_PWM_INSTANCE(DT_INST_REG_ADDR(inst)), \
487+
}; \
488+
static uint16_t pwm_##inst##_seq_values[NRF_PWM_CHANNEL_COUNT] \
489+
PWM_MEMORY_SECTION(inst); \
490+
PINCTRL_DT_INST_DEFINE(inst); \
491+
static const struct pwm_nrfx_config pwm_nrfx_##inst##_config = { \
492+
.initial_config = { \
493+
.skip_gpio_cfg = true, \
494+
.skip_psel_cfg = true, \
495+
.base_clock = NRF_PWM_CLK_1MHz, \
496+
.count_mode = (DT_INST_PROP(inst, center_aligned) \
497+
? NRF_PWM_MODE_UP_AND_DOWN \
498+
: NRF_PWM_MODE_UP), \
499+
.top_value = 1000, \
500+
.load_mode = NRF_PWM_LOAD_INDIVIDUAL, \
501+
.step_mode = NRF_PWM_STEP_TRIGGERED, \
502+
}, \
503+
.seq.values.p_raw = pwm_##inst##_seq_values, \
504+
.seq.length = NRF_PWM_CHANNEL_COUNT, \
505+
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
506+
.clock_freq = COND_CODE_1(DT_INST_CLOCKS_HAS_IDX(inst, 0), \
507+
(DT_PROP(DT_INST_CLOCKS_CTLR(inst), clock_frequency)), \
508+
(16ul * 1000ul * 1000ul)), \
509+
IF_ENABLED(CONFIG_DCACHE, \
510+
(.mem_attr = PWM_GET_MEM_ATTR(inst),)) \
511+
IF_ENABLED(PWM_NRFX_USE_CLOCK_CONTROL, \
512+
(.clk_dev = PWM_NRFX_IS_FAST(inst) \
513+
? DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)) \
514+
: NULL, \
515+
.clk_spec = { \
516+
.frequency = \
517+
NRF_PERIPH_GET_FREQUENCY(DT_DRV_INST(inst)), \
518+
},)) \
519+
}; \
520+
static int pwm_nrfx_init##inst(const struct device *dev) \
521+
{ \
522+
IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \
523+
nrfx_pwm_irq_handler, &pwm_nrfx_##inst##_data.pwm, 0); \
524+
return pwm_nrfx_init(dev); \
525+
}; \
526+
PM_DEVICE_DT_INST_DEFINE(inst, pwm_nrfx_pm_action); \
527+
DEVICE_DT_INST_DEINIT_DEFINE(inst, \
528+
pwm_nrfx_init##inst, NULL, \
529+
PM_DEVICE_DT_INST_GET(inst), \
530+
&pwm_nrfx_##inst##_data, \
531+
&pwm_nrfx_##inst##_config, \
532+
POST_KERNEL, PWM_INIT_PRIORITY(inst), \
533+
&pwm_nrfx_drv_api_funcs)
534+
535+
DT_INST_FOREACH_STATUS_OKAY(PWM_NRFX_DEFINE)

0 commit comments

Comments
 (0)