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:
parent
e021108ace
commit
05fd40012f
|
@ -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";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue