drivers: pwm_nxp_s32_emios: prepare for support pwm capture

This prepares support pwm capture APIs by extended current pwm
shim driver but use a differrence hal component:

- Introduce a Kconfig options that will be set when PWM pulse
  generation API is used, it is also used to select the hal
  component. Guarding current code inside this Kconfig option

- Increase #pwm-cells to 3, flags is supported for PWM capture

- Do not require duty-cycle and polarity be set in dt, PWM
  capture doesn't need it.

- Rename emum value for pwm-mode to keep only key information

- Add preprocessor in case no channel is configured for generate
  PWM output, to avoid warning when build

Signed-off-by: Dat Nguyen Duy <dat.nguyenduy@nxp.com>
This commit is contained in:
Dat Nguyen Duy 2023-09-24 00:01:23 +07:00 committed by Carles Cufí
parent e021108ace
commit 05fd40012f
4 changed files with 141 additions and 69 deletions

View file

@ -65,15 +65,15 @@
compatible = "pwm-leds";
user_led1_blue_pwm: user_led1_blue {
pwms = <&emios1_pwm 5 PWM_MSEC(20)>;
pwms = <&emios1_pwm 5 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
};
user_led1_green_pwm: user_led1_green {
pwms = <&emios1_pwm 10 PWM_MSEC(20)>;
pwms = <&emios1_pwm 10 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
};
user_led1_red_pwm: user_led1_red {
pwms = <&emios0_pwm 19 PWM_MSEC(20)>;
pwms = <&emios0_pwm 19 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
};
};
@ -441,7 +441,7 @@
/* Default clock for internal counter for PWM channel 0-7 is 100Khz */
pwm_0 {
channel = <0>;
pwm-mode = "MODE_OPWFMB";
pwm-mode = "OPWFMB";
period = <65535>;
duty-cycle = <0>;
prescaler = <8>;
@ -450,7 +450,7 @@
pwm_1 {
channel = <1>;
pwm-mode = "MODE_OPWFMB";
pwm-mode = "OPWFMB";
period = <65535>;
duty-cycle = <0>;
prescaler = <8>;
@ -459,7 +459,7 @@
pwm_2 {
channel = <2>;
pwm-mode = "MODE_OPWFMB";
pwm-mode = "OPWFMB";
period = <65535>;
duty-cycle = <0>;
prescaler = <8>;
@ -468,7 +468,7 @@
pwm_3 {
channel = <3>;
pwm-mode = "MODE_OPWFMB";
pwm-mode = "OPWFMB";
period = <65535>;
duty-cycle = <0>;
prescaler = <8>;
@ -477,7 +477,7 @@
pwm_4 {
channel = <4>;
pwm-mode = "MODE_OPWFMB";
pwm-mode = "OPWFMB";
period = <65535>;
duty-cycle = <0>;
prescaler = <8>;
@ -486,7 +486,7 @@
pwm_5 {
channel = <5>;
pwm-mode = "MODE_OPWFMB";
pwm-mode = "OPWFMB";
period = <65535>;
duty-cycle = <0>;
prescaler = <8>;
@ -495,7 +495,7 @@
pwm_6 {
channel = <6>;
pwm-mode = "MODE_OPWFMB";
pwm-mode = "OPWFMB";
period = <65535>;
duty-cycle = <0>;
prescaler = <8>;
@ -504,7 +504,7 @@
pwm_7 {
channel = <7>;
pwm-mode = "MODE_OPWFMB";
pwm-mode = "OPWFMB";
period = <65535>;
duty-cycle = <0>;
prescaler = <8>;
@ -515,7 +515,7 @@
channel = <19>;
master-bus = <&emios0_bus_a>;
duty-cycle = <0>;
pwm-mode = "MODE_OPWMB";
pwm-mode = "OPWMB";
polarity = "ACTIVE_LOW";
};
};
@ -554,7 +554,7 @@
channel = <10>;
master-bus = <&emios1_bus_a>;
duty-cycle = <0>;
pwm-mode = "MODE_OPWMB";
pwm-mode = "OPWMB";
polarity = "ACTIVE_LOW";
};
@ -562,7 +562,7 @@
channel = <5>;
master-bus = <&emios1_bus_f>;
duty-cycle = <0>;
pwm-mode = "MODE_OPWMB";
pwm-mode = "OPWMB";
polarity = "ACTIVE_LOW";
};
};

View file

@ -8,6 +8,7 @@
#include <zephyr/drivers/pwm.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/clock_control.h>
#include <Emios_Mcl_Ip.h>
#include <Emios_Pwm_Ip.h>
@ -21,16 +22,23 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_PWM_LOG_LEVEL);
* Need to fill to this array at runtime, cannot do at build time like
* the HAL over configuration tool due to limitation of the integration
*/
#if EMIOS_PWM_IP_USED
extern uint8 eMios_Pwm_Ip_IndexInChState[EMIOS_PWM_IP_INSTANCE_COUNT][EMIOS_PWM_IP_CHANNEL_COUNT];
#endif
struct pwm_nxp_s32_data {
uint32_t emios_clk;
#if EMIOS_PWM_IP_USED
uint8_t start_pwm_ch;
#endif
};
#if EMIOS_PWM_IP_USED
struct pwm_nxp_s32_pulse_info {
uint8_t pwm_pulse_channels;
Emios_Pwm_Ip_ChannelConfigType *pwm_info;
};
#endif
struct pwm_nxp_s32_config {
eMIOS_Type *base;
@ -38,9 +46,13 @@ struct pwm_nxp_s32_config {
const struct device *clock_dev;
clock_control_subsys_t clock_subsys;
const struct pinctrl_dev_config *pincfg;
#if EMIOS_PWM_IP_USED
struct pwm_nxp_s32_pulse_info *pulse_info;
#endif
};
#if EMIOS_PWM_IP_USED
#ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED
static int pwm_nxp_s32_set_cycles_internal_timebase(uint8_t instance, uint32_t channel,
uint32_t period_cycles, uint32_t pulse_cycles)
@ -116,26 +128,31 @@ static int pwm_nxp_s32_set_cycles(const struct device *dev, uint32_t channel,
pwm_flags_t flags)
{
const struct pwm_nxp_s32_config *config = dev->config;
struct pwm_nxp_s32_data *data = dev->data;
Emios_Pwm_Ip_PwmModeType mode;
Emios_Pwm_Ip_ChannelConfigType *pwm_info;
uint8_t logic_ch;
if (channel >= EMIOS_PWM_IP_CHANNEL_COUNT) {
LOG_ERR("invalid channel %d", channel);
return -EINVAL;
}
mode = Emios_Pwm_Ip_GetChannelMode(config->instance, channel);
if (mode == EMIOS_PWM_IP_MODE_NODEFINE) {
if (eMios_Pwm_Ip_IndexInChState[config->instance][channel] >=
EMIOS_PWM_IP_NUM_OF_CHANNELS_USED) {
LOG_ERR("Channel %d is not configured for PWM", channel);
return -EINVAL;
}
if (flags) {
logic_ch = eMios_Pwm_Ip_IndexInChState[config->instance][channel] - data->start_pwm_ch;
pwm_info = &config->pulse_info->pwm_info[logic_ch];
if ((flags & PWM_POLARITY_MASK) == pwm_info->OutputPolarity) {
LOG_ERR("Only support configuring output polarity at boot time");
return -ENOTSUP;
}
switch (mode) {
switch (pwm_info->Mode) {
#ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED
case EMIOS_PWM_IP_MODE_OPWFMB_FLAG:
return pwm_nxp_s32_set_cycles_internal_timebase(config->instance, channel,
@ -174,6 +191,7 @@ static int pwm_nxp_s32_set_cycles(const struct device *dev, uint32_t channel,
return 0;
}
#endif
static int pwm_nxp_s32_get_cycles_per_sec(const struct device *dev,
uint32_t channel,
@ -182,14 +200,21 @@ static int pwm_nxp_s32_get_cycles_per_sec(const struct device *dev,
const struct pwm_nxp_s32_config *config = dev->config;
struct pwm_nxp_s32_data *data = dev->data;
uint8_t internal_prescaler, global_prescaler, master_bus;
uint8_t master_bus = 0xFFU;
uint8_t internal_prescaler, global_prescaler;
if (Emios_Pwm_Ip_GetChannelMode(config->instance, channel) == EMIOS_PWM_IP_MODE_NODEFINE) {
#if EMIOS_PWM_IP_USED
if (eMios_Pwm_Ip_IndexInChState[config->instance][channel] <
EMIOS_PWM_IP_NUM_OF_CHANNELS_USED) {
master_bus = Emios_Pwm_Ip_GetMasterBusChannel(config->instance, channel);
}
#endif
if (master_bus == 0xFFU) {
LOG_ERR("Channel %d is not configured for PWM", channel);
return -EINVAL;
}
master_bus = Emios_Pwm_Ip_GetMasterBusChannel(config->instance, channel);
internal_prescaler = (config->base->CH.UC[master_bus].C2 & eMIOS_C2_UCEXTPRE_MASK) >>
eMIOS_C2_UCEXTPRE_SHIFT;
@ -205,17 +230,36 @@ static int pwm_nxp_s32_get_cycles_per_sec(const struct device *dev,
return 0;
}
static int pwm_nxp_s32_init(const struct device *dev)
#if EMIOS_PWM_IP_USED
static int pwm_nxp_s32_pulse_gen_init(const struct device *dev)
{
const struct pwm_nxp_s32_config *config = dev->config;
struct pwm_nxp_s32_data *data = dev->data;
const Emios_Pwm_Ip_ChannelConfigType *pwm_info;
int err = 0;
uint8_t ch_id;
uint8_t ch_id;
static uint8_t logic_ch;
data->start_pwm_ch = logic_ch;
for (ch_id = 0; ch_id < config->pulse_info->pwm_pulse_channels; ch_id++) {
pwm_info = &config->pulse_info->pwm_info[ch_id];
eMios_Pwm_Ip_IndexInChState[config->instance][pwm_info->ChannelId] = logic_ch++;
Emios_Pwm_Ip_InitChannel(config->instance, pwm_info);
}
return 0;
}
#endif
static int pwm_nxp_s32_init(const struct device *dev)
{
const struct pwm_nxp_s32_config *config = dev->config;
struct pwm_nxp_s32_data *data = dev->data;
int err = 0;
if (!device_is_ready(config->clock_dev)) {
return -ENODEV;
}
@ -230,11 +274,12 @@ static int pwm_nxp_s32_init(const struct device *dev)
return err;
}
for (ch_id = 0; ch_id < config->pulse_info->pwm_pulse_channels; ch_id++) {
pwm_info = &config->pulse_info->pwm_info[ch_id];
eMios_Pwm_Ip_IndexInChState[config->instance][pwm_info->ChannelId] = logic_ch++;
Emios_Pwm_Ip_InitChannel(config->instance, pwm_info);
#if EMIOS_PWM_IP_USED
err = pwm_nxp_s32_pulse_gen_init(dev);
if (err < 0) {
return err;
}
#endif
return err;
}
@ -244,18 +289,6 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = {
.get_cycles_per_sec = pwm_nxp_s32_get_cycles_per_sec,
};
/* Macros used to glue devicetree with RTD's definition */
#define BUS_A EMIOS_PWM_IP_BUS_A
#define BUS_B EMIOS_PWM_IP_BUS_BCDE
#define BUS_C EMIOS_PWM_IP_BUS_BCDE
#define BUS_D EMIOS_PWM_IP_BUS_BCDE
#define BUS_E EMIOS_PWM_IP_BUS_BCDE
#define BUS_F EMIOS_PWM_IP_BUS_F
#define EMIOS_PWM_MODE(mode) DT_CAT3(EMIOS_PWM_IP_, mode, _FLAG)
#define EMIOS_PWM_POLARITY(mode) DT_CAT(EMIOS_PWM_IP_, mode)
#define EMIOS_PWM_PS_SRC(mode) DT_CAT(EMIOS_PWM_IP_PS_SRC_, mode)
/*
* If timebase is configured in MCB up/down count mode: pwm period = (2 * master bus's period - 2)
*/
@ -265,24 +298,31 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = {
(DT_PROP_BY_PHANDLE(node_id, master_bus, period)))
#define EMIOS_PWM_IS_MODE_OPWFMB(node_id) \
DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWFMB)
DT_ENUM_HAS_VALUE(node_id, pwm_mode, OPWFMB)
#define EMIOS_PWM_IS_MODE_OPWMCB(node_id) \
UTIL_OR(DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWMCB_TRAIL_EDGE), \
DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWMCB_LEAD_EDGE)) \
UTIL_OR(DT_ENUM_HAS_VALUE(node_id, pwm_mode, OPWMCB_TRAIL_EDGE), \
DT_ENUM_HAS_VALUE(node_id, pwm_mode, OPWMCB_LEAD_EDGE)) \
#define EMIOS_PWM_IS_MODE_OPWMB(node_id) \
DT_ENUM_HAS_VALUE(node_id, pwm_mode, MODE_OPWMB)
DT_ENUM_HAS_VALUE(node_id, pwm_mode, OPWMB)
#define EMIOS_PWM_LOG(node_id, msg) \
DT_NODE_PATH(node_id) ": " DT_PROP(node_id, pwm_mode) ": " msg \
#define EMIOS_PWM_VERIFY_MASTER_BUS(node_id) \
BUILD_ASSERT(BIT(DT_PROP(node_id, channel)) & \
DT_PROP_BY_PHANDLE(node_id, master_bus, channel_mask), \
"Node "DT_NODE_PATH(node_id)": invalid master bus");
EMIOS_PWM_LOG(node_id, "invalid master bus"));
#define EMIOS_PWM_LOG(node_id, msg) \
DT_NODE_PATH(node_id) ": " DT_PROP(node_id, pwm_mode) ": " msg \
#define EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \
BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, duty_cycle), \
EMIOS_PWM_LOG(node_id, "duty-cycle must be configured")); \
BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, polarity), \
EMIOS_PWM_LOG(node_id, "polarity must be configured"));
#define EMIOS_PWM_VERIFY_MODE_OPWFMB(node_id) \
EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \
BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, period), \
EMIOS_PWM_LOG(node_id, "period must be configured")); \
BUILD_ASSERT(IN_RANGE(DT_PROP(node_id, period), EMIOS_PWM_IP_MIN_CNT_VAL + 1, \
@ -298,6 +338,7 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = {
EMIOS_PWM_LOG(node_id, "phase-shift must not be configured"));
#define EMIOS_PWM_VERIFY_MODE_OPWMCB(node_id) \
EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \
BUILD_ASSERT(DT_ENUM_HAS_VALUE(DT_PHANDLE(node_id, master_bus), mode, \
MCB_UP_DOWN_COUNTER), \
EMIOS_PWM_LOG(node_id, "master-bus must be configured in MCB up-down")); \
@ -319,6 +360,7 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = {
" always use prescalered source")); \
#define EMIOS_PWM_VERIFY_MODE_OPWMB(node_id) \
EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \
BUILD_ASSERT(DT_ENUM_HAS_VALUE(DT_PHANDLE(node_id, master_bus), mode, MCB_UP_COUNTER), \
EMIOS_PWM_LOG(node_id, "master-bus must be configured in MCB up")); \
BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, period), \
@ -335,7 +377,7 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = {
EMIOS_PWM_LOG(node_id, "prescaler-src must not be configured," \
" always use prescalered source")); \
#define EMIOS_PWM_VERIFY_CONFIG(node_id) \
#define _EMIOS_PWM_VERIFY_CONFIG(node_id) \
IF_ENABLED(DT_NODE_HAS_PROP(node_id, master_bus), \
(EMIOS_PWM_VERIFY_MASTER_BUS(node_id))) \
IF_ENABLED(EMIOS_PWM_IS_MODE_OPWFMB(node_id), \
@ -345,15 +387,31 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = {
IF_ENABLED(EMIOS_PWM_IS_MODE_OPWMB(node_id), \
(EMIOS_PWM_VERIFY_MODE_OPWMB(node_id))) \
#define EMIOS_PWM_CONFIG(node_id) \
#if EMIOS_PWM_IP_USED
/* Macros used to glue devicetree with RTD's definition */
#define EMIOS_PWM_BUS_A EMIOS_PWM_IP_BUS_A
#define EMIOS_PWM_BUS_B EMIOS_PWM_IP_BUS_BCDE
#define EMIOS_PWM_BUS_C EMIOS_PWM_IP_BUS_BCDE
#define EMIOS_PWM_BUS_D EMIOS_PWM_IP_BUS_BCDE
#define EMIOS_PWM_BUS_E EMIOS_PWM_IP_BUS_BCDE
#define EMIOS_PWM_BUS_F EMIOS_PWM_IP_BUS_F
#define EMIOS_PWM_BUS(mode) DT_CAT(EMIOS_PWM_, mode)
#define EMIOS_PWM_MODE(mode) DT_CAT3(EMIOS_PWM_IP_MODE_, mode, _FLAG)
#define EMIOS_PWM_POLARITY(mode) DT_CAT(EMIOS_PWM_IP_, mode)
#define EMIOS_PWM_PS_SRC(mode) DT_CAT(EMIOS_PWM_IP_PS_SRC_, mode)
#define _EMIOS_PWM_PULSE_GEN_CONFIG(node_id) \
{ \
.ChannelId = DT_PROP(node_id, channel), \
.Mode = EMIOS_PWM_MODE(DT_STRING_TOKEN(node_id, pwm_mode)), \
.InternalPsSrc = EMIOS_PWM_PS_SRC(DT_STRING_TOKEN(node_id, prescaler_src)), \
.InternalPs = DT_PROP_OR(node_id, prescaler, \
DT_PROP_BY_PHANDLE(node_id, master_bus, prescaler)) - 1,\
.Timebase = DT_STRING_TOKEN_OR(DT_PHANDLE(node_id, master_bus), bus_type, \
EMIOS_PWM_IP_BUS_INTERNAL), \
.Timebase = COND_CODE_1(DT_NODE_HAS_PROP(node_id, master_bus), \
(EMIOS_PWM_BUS(DT_STRING_TOKEN( \
DT_PHANDLE(node_id, master_bus), bus_type))), \
(EMIOS_PWM_IP_BUS_INTERNAL)), \
.PhaseShift = DT_PROP(node_id, phase_shift), \
.DeadTime = DT_PROP(node_id, dead_time), \
.OutputDisableSource = EMIOS_PWM_IP_OUTPUT_DISABLE_NONE, \
@ -363,16 +421,25 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = {
.DutyCycle = DT_PROP(node_id, duty_cycle), \
},
#define EMIOS_PWM_GENERATE_CONFIG(n) \
DT_INST_FOREACH_CHILD_STATUS_OKAY(n, EMIOS_PWM_VERIFY_CONFIG) \
#define EMIOS_PWM_PULSE_GEN_CONFIG(n) \
const Emios_Pwm_Ip_ChannelConfigType emios_pwm_##n##_init[] = { \
DT_INST_FOREACH_CHILD_STATUS_OKAY(n, EMIOS_PWM_CONFIG) \
DT_INST_FOREACH_CHILD_STATUS_OKAY(n, _EMIOS_PWM_PULSE_GEN_CONFIG) \
}; \
const struct pwm_nxp_s32_pulse_info emios_pwm_##n##_info = { \
.pwm_pulse_channels = ARRAY_SIZE(emios_pwm_##n##_init), \
.pwm_info = (Emios_Pwm_Ip_ChannelConfigType *)emios_pwm_##n##_init, \
};
#define EMIOS_PWM_PULSE_GEN_GET_CONFIG(n) \
.pulse_info = (struct pwm_nxp_s32_pulse_info *)&emios_pwm_##n##_info,
#else
#define EMIOS_PWM_PULSE_GEN_CONFIG(n)
#define EMIOS_PWM_PULSE_GEN_GET_CONFIG(n)
#endif
#define EMIOS_PWM_VERIFY_CONFIG(n) \
DT_INST_FOREACH_CHILD_STATUS_OKAY(n, _EMIOS_PWM_VERIFY_CONFIG)
#define EMIOS_NXP_S32_INSTANCE_CHECK(idx, node_id) \
((DT_REG_ADDR(node_id) == IP_EMIOS_##idx##_BASE) ? idx : 0)
@ -381,14 +448,15 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = {
#define PWM_NXP_S32_INIT_DEVICE(n) \
PINCTRL_DT_INST_DEFINE(n); \
EMIOS_PWM_GENERATE_CONFIG(n) \
EMIOS_PWM_VERIFY_CONFIG(n) \
EMIOS_PWM_PULSE_GEN_CONFIG(n) \
static const struct pwm_nxp_s32_config pwm_nxp_s32_config_##n = { \
.base = (eMIOS_Type *)DT_REG_ADDR(DT_INST_PARENT(n)), \
.instance = EMIOS_NXP_S32_GET_INSTANCE(DT_INST_PARENT(n)), \
.clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_INST_PARENT(n))), \
.clock_subsys = (clock_control_subsys_t)DT_CLOCKS_CELL(DT_INST_PARENT(n), name),\
.pulse_info = (struct pwm_nxp_s32_pulse_info *)&emios_pwm_##n##_info, \
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n) \
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
EMIOS_PWM_PULSE_GEN_GET_CONFIG(n) \
}; \
static struct pwm_nxp_s32_data pwm_nxp_s32_data_##n; \
DEVICE_DT_INST_DEFINE(n, \

View file

@ -667,7 +667,7 @@
pwm {
compatible = "nxp,s32-emios-pwm";
#pwm-cells = <2>;
#pwm-cells = <3>;
status = "disabled";
};
};
@ -721,7 +721,7 @@
pwm {
compatible = "nxp,s32-emios-pwm";
#pwm-cells = <2>;
#pwm-cells = <3>;
status = "disabled";
};
};
@ -775,7 +775,7 @@
pwm {
compatible = "nxp,s32-emios-pwm";
#pwm-cells = <2>;
#pwm-cells = <3>;
status = "disabled";
};
};

View file

@ -1,3 +1,6 @@
# Copyright 2023 NXP
# SPDX-License-Identifier: Apache-2.0
description: |
NXP S32 eMIOS PWM node for S32 SoCs. Each channel in eMIOS can be configured
to use for PWM operation. There are several PWM modes supported by this module,
@ -9,7 +12,7 @@ description: |
emios0_pwm: pwm {
pwm_0 {
channel = <0>;
pwm-mode = "MODE_OPWFMB";
pwm-mode = "OPWFMB";
prescaler = <8>;
period = <65534>;
duty-cycle = <32768>;
@ -19,7 +22,7 @@ description: |
pwm_1 {
channel = <1>;
master-bus = <&emios1_bus_a>;
pwm-mode = "MODE_OPWMB";
pwm-mode = "OPWMB";
duty-cycle = <32768>;
phase-shift = <100>;
polarity = "ACTIVE_LOW";
@ -28,7 +31,7 @@ description: |
pwm_2 {
channel = <2>;
master-bus = <&emios1_bus_b>;
pwm-mode = "MODE_OPWMCB_LEAD_EDGE";
pwm-mode = "OPWMCB_LEAD_EDGE";
duty-cycle = <32768>;
dead-time = <100>;
polarity = "ACTIVE_LOW";
@ -53,12 +56,13 @@ properties:
required: true
"#pwm-cells":
const: 2
const: 3
pwm-cells:
- channel
# Period in terms of nanoseconds
- period
- flags
child-binding:
description: |
@ -97,10 +101,10 @@ child-binding:
at runtime will impact to all channels share the same timebase,
The new period and cycle take effect in next period boundary.
enum:
- "MODE_OPWFMB"
- "MODE_OPWMB"
- "MODE_OPWMCB_TRAIL_EDGE"
- "MODE_OPWMCB_LEAD_EDGE"
- "OPWFMB"
- "OPWMB"
- "OPWMCB_TRAIL_EDGE"
- "OPWMCB_LEAD_EDGE"
polarity:
type: string