Skip to content

Commit 5a49993

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 c475e9f commit 5a49993

File tree

1 file changed

+91
-88
lines changed

1 file changed

+91
-88
lines changed

drivers/pwm/pwm_nrfx.c

Lines changed: 91 additions & 88 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>
@@ -33,10 +36,7 @@ LOG_MODULE_REGISTER(pwm_nrfx, CONFIG_PWM_LOG_LEVEL);
3336
#define ANOMALY_109_EGU_IRQ_CONNECT(idx)
3437
#endif
3538

36-
#define PWM(dev_idx) DT_NODELABEL(pwm##dev_idx)
37-
#define PWM_PROP(dev_idx, prop) DT_PROP(PWM(dev_idx), prop)
38-
#define PWM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(PWM(idx), prop)
39-
#define PWM_NRFX_IS_FAST(idx) NRF_DT_IS_FAST(PWM(idx))
39+
#define PWM_NRFX_IS_FAST(inst) NRF_DT_IS_FAST(DT_DRV_INST(inst))
4040

4141
#if NRF_DT_INST_ANY_IS_FAST
4242
#define PWM_NRFX_FAST_PRESENT 1
@@ -57,7 +57,6 @@ BUILD_ASSERT(!IS_ENABLED(CONFIG_PM_DEVICE_SYSTEM_MANAGED));
5757
(compare_value | (inverted ? 0 : PWM_NRFX_CH_POLARITY_MASK))
5858

5959
struct pwm_nrfx_config {
60-
nrfx_pwm_t pwm;
6160
nrfx_pwm_config_t initial_config;
6261
nrf_pwm_sequence_t seq;
6362
const struct pinctrl_dev_config *pcfg;
@@ -72,6 +71,7 @@ struct pwm_nrfx_config {
7271
};
7372

7473
struct pwm_nrfx_data {
74+
nrfx_pwm_t pwm;
7575
uint32_t period_cycles;
7676
/* Bit mask indicating channels that need the PWM generation. */
7777
uint8_t pwm_needed;
@@ -145,7 +145,7 @@ static bool pwm_period_check_and_set(const struct device *dev,
145145
data->period_cycles = period_cycles;
146146
data->prescaler = prescaler;
147147

148-
nrf_pwm_configure(config->pwm.p_reg,
148+
nrf_pwm_configure(data->pwm.p_reg,
149149
data->prescaler,
150150
config->initial_config.count_mode,
151151
(uint16_t)countertop);
@@ -160,26 +160,25 @@ static bool pwm_period_check_and_set(const struct device *dev,
160160
return false;
161161
}
162162

163-
static bool channel_psel_get(uint32_t channel, uint32_t *psel,
164-
const struct pwm_nrfx_config *config)
163+
static bool channel_psel_get(uint32_t channel, uint32_t *psel, struct pwm_nrfx_data *data)
165164
{
166-
*psel = nrf_pwm_pin_get(config->pwm.p_reg, (uint8_t)channel);
165+
*psel = nrf_pwm_pin_get(data->pwm.p_reg, (uint8_t)channel);
167166

168167
return (((*psel & PWM_PSEL_OUT_CONNECT_Msk) >> PWM_PSEL_OUT_CONNECT_Pos)
169168
== PWM_PSEL_OUT_CONNECT_Connected);
170169
}
171170

172171
static int stop_pwm(const struct device *dev)
173172
{
174-
const struct pwm_nrfx_config *config = dev->config;
173+
struct pwm_nrfx_data *data = dev->data;
175174

176175
/* Don't wait here for the peripheral to actually stop. Instead,
177-
* ensure it is stopped before starting the next playback.
178-
*/
179-
nrfx_pwm_stop(&config->pwm, false);
176+
* ensure it is stopped before starting the next playback.
177+
*/
178+
nrfx_pwm_stop(&data->pwm, false);
180179

181180
#if PWM_NRFX_USE_CLOCK_CONTROL
182-
struct pwm_nrfx_data *data = dev->data;
181+
const struct pwm_nrfx_config *config = dev->config;
183182

184183
if (data->clock_requested) {
185184
int ret = nrf_clock_control_release(config->clk_dev, &config->clk_spec);
@@ -268,7 +267,7 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
268267
if (!needs_pwm) {
269268
uint32_t psel;
270269

271-
if (channel_psel_get(channel, &psel, config)) {
270+
if (channel_psel_get(channel, &psel, data)) {
272271
uint32_t out_level = (pulse_cycles == 0) ? 0 : 1;
273272

274273
if (inverted) {
@@ -323,7 +322,7 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
323322
* and till that moment, it ignores any start requests,
324323
* so ensure here that it is stopped.
325324
*/
326-
while (!nrfx_pwm_stopped_check(&config->pwm)) {
325+
while (!nrfx_pwm_stopped_check(&data->pwm)) {
327326
}
328327
}
329328

@@ -346,7 +345,7 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
346345
data->clock_requested = true;
347346
}
348347
#endif
349-
nrfx_pwm_simple_playback(&config->pwm, &config->seq, 1,
348+
nrfx_pwm_simple_playback(&data->pwm, &config->seq, 1,
350349
NRFX_PWM_FLAG_NO_EVT_FINISHED);
351350
}
352351

@@ -371,14 +370,16 @@ static DEVICE_API(pwm, pwm_nrfx_drv_api_funcs) = {
371370
static int pwm_resume(const struct device *dev)
372371
{
373372
const struct pwm_nrfx_config *config = dev->config;
373+
struct pwm_nrfx_data *data = dev->data;
374+
374375
uint8_t initially_inverted = 0;
375376

376377
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
377378

378379
for (size_t i = 0; i < NRF_PWM_CHANNEL_COUNT; i++) {
379380
uint32_t psel;
380381

381-
if (channel_psel_get(i, &psel, config)) {
382+
if (channel_psel_get(i, &psel, data)) {
382383
/* Mark channels as inverted according to what initial
383384
* state of their outputs has been set by pinctrl (high
384385
* idle state means that the channel is inverted).
@@ -400,6 +401,7 @@ static int pwm_resume(const struct device *dev)
400401
static int pwm_suspend(const struct device *dev)
401402
{
402403
const struct pwm_nrfx_config *config = dev->config;
404+
const struct pwm_nrfx_data *data = dev->data;
403405

404406
int ret = stop_pwm(dev);
405407

@@ -408,7 +410,7 @@ static int pwm_suspend(const struct device *dev)
408410
return ret;
409411
}
410412

411-
while (!nrfx_pwm_stopped_check(&config->pwm)) {
413+
while (!nrfx_pwm_stopped_check(&data->pwm)) {
412414
}
413415

414416
memset(dev->data, 0, sizeof(struct pwm_nrfx_data));
@@ -434,34 +436,36 @@ static int pwm_nrfx_pm_action(const struct device *dev,
434436
static int pwm_nrfx_init(const struct device *dev)
435437
{
436438
const struct pwm_nrfx_config *config = dev->config;
437-
nrfx_err_t err;
439+
struct pwm_nrfx_data *data = dev->data;
440+
441+
int err;
438442

439443
ANOMALY_109_EGU_IRQ_CONNECT(NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE);
440444

441445
if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
442446
(void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
443447
}
444448

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

451455
return pm_device_driver_init(dev, pwm_nrfx_pm_action);
452456
}
453457

454-
#define PWM_MEM_REGION(idx) DT_PHANDLE(PWM(idx), memory_regions)
458+
#define PWM_MEM_REGION(inst) DT_PHANDLE(DT_DRV_INST(inst), memory_regions)
455459

456-
#define PWM_MEMORY_SECTION(idx) \
457-
COND_CODE_1(PWM_HAS_PROP(idx, memory_regions), \
460+
#define PWM_MEMORY_SECTION(inst) \
461+
COND_CODE_1(DT_NODE_HAS_PROP(inst, memory_regions), \
458462
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
459-
PWM_MEM_REGION(idx)))))), \
463+
PWM_MEM_REGION(inst)))))), \
460464
())
461465

462-
#define PWM_GET_MEM_ATTR(idx) \
463-
COND_CODE_1(PWM_HAS_PROP(idx, memory_regions), \
464-
(DT_PROP_OR(PWM_MEM_REGION(idx), zephyr_memory_attr, 0)), (0))
466+
#define PWM_GET_MEM_ATTR(inst) \
467+
COND_CODE_1(DT_NODE_HAS_PROP(inst, memory_regions), \
468+
(DT_PROP_OR(PWM_MEM_REGION(inst), zephyr_memory_attr, 0)), (0))
465469

466470
/* Fast instances depend on the global HSFLL clock controller (as they need
467471
* to request the highest frequency from it to operate correctly), so they
@@ -470,66 +474,65 @@ static int pwm_nrfx_init(const struct device *dev)
470474
*/
471475
#if defined(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY) && \
472476
CONFIG_PWM_INIT_PRIORITY < CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY
473-
#define PWM_INIT_PRIORITY(idx) \
474-
COND_CODE_1(PWM_NRFX_IS_FAST(idx), \
477+
#define PWM_INIT_PRIORITY(inst) \
478+
COND_CODE_1(PWM_NRFX_IS_FAST(inst), \
475479
(UTIL_INC(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL_INIT_PRIORITY)), \
476480
(CONFIG_PWM_INIT_PRIORITY))
477481
#else
478-
#define PWM_INIT_PRIORITY(idx) CONFIG_PWM_INIT_PRIORITY
482+
#define PWM_INIT_PRIORITY(inst) CONFIG_PWM_INIT_PRIORITY
479483
#endif
480484

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

0 commit comments

Comments
 (0)