drivers: pwm: mcux_ftm: use device tree for obtaining clock frequency
Use clock specified in the device tree for obtaining the source clock frequency for the pwm_mcux_ftm driver instead of relying on having an NXP Kinetis MCG clock available in all SoCs supporting FlexTimer (FTM) modules. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
a9a839179f
commit
84c74993d4
7 changed files with 65 additions and 13 deletions
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <drivers/clock_control.h>
|
||||
#include <errno.h>
|
||||
#include <drivers/pwm.h>
|
||||
#include <soc.h>
|
||||
|
@ -18,7 +19,8 @@ LOG_MODULE_REGISTER(pwm_mcux_ftm);
|
|||
|
||||
struct mcux_ftm_config {
|
||||
FTM_Type *base;
|
||||
clock_name_t clock_source;
|
||||
char *clock_name;
|
||||
clock_control_subsys_t clock_subsys;
|
||||
ftm_clock_source_t ftm_clock_source;
|
||||
ftm_clock_prescale_t prescale;
|
||||
u8_t channel_count;
|
||||
|
@ -26,6 +28,7 @@ struct mcux_ftm_config {
|
|||
};
|
||||
|
||||
struct mcux_ftm_data {
|
||||
u32_t clock_freq;
|
||||
u32_t period_cycles;
|
||||
ftm_chnl_pwm_signal_param_t channel[MAX_CHANNELS];
|
||||
};
|
||||
|
@ -55,7 +58,6 @@ static int mcux_ftm_pin_set(struct device *dev, u32_t pwm,
|
|||
pulse_cycles, period_cycles, duty_cycle);
|
||||
|
||||
if (period_cycles != data->period_cycles) {
|
||||
u32_t clock_freq;
|
||||
u32_t pwm_freq;
|
||||
status_t status;
|
||||
|
||||
|
@ -66,10 +68,11 @@ static int mcux_ftm_pin_set(struct device *dev, u32_t pwm,
|
|||
|
||||
data->period_cycles = period_cycles;
|
||||
|
||||
clock_freq = CLOCK_GetFreq(config->clock_source);
|
||||
pwm_freq = (clock_freq >> config->prescale) / period_cycles;
|
||||
pwm_freq = (data->clock_freq >> config->prescale) /
|
||||
period_cycles;
|
||||
|
||||
LOG_DBG("pwm_freq=%d, clock_freq=%d", pwm_freq, clock_freq);
|
||||
LOG_DBG("pwm_freq=%d, clock_freq=%d", pwm_freq,
|
||||
data->clock_freq);
|
||||
|
||||
if (pwm_freq == 0U) {
|
||||
LOG_ERR("Could not set up pwm_freq=%d", pwm_freq);
|
||||
|
@ -80,7 +83,7 @@ static int mcux_ftm_pin_set(struct device *dev, u32_t pwm,
|
|||
|
||||
status = FTM_SetupPwm(config->base, data->channel,
|
||||
config->channel_count, config->mode,
|
||||
pwm_freq, clock_freq);
|
||||
pwm_freq, data->clock_freq);
|
||||
|
||||
if (status != kStatus_Success) {
|
||||
LOG_ERR("Could not set up pwm");
|
||||
|
@ -102,8 +105,9 @@ static int mcux_ftm_get_cycles_per_sec(struct device *dev, u32_t pwm,
|
|||
u64_t *cycles)
|
||||
{
|
||||
const struct mcux_ftm_config *config = dev->config->config_info;
|
||||
struct mcux_ftm_data *data = dev->driver_data;
|
||||
|
||||
*cycles = CLOCK_GetFreq(config->clock_source) >> config->prescale;
|
||||
*cycles = data->clock_freq >> config->prescale;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -113,6 +117,7 @@ static int mcux_ftm_init(struct device *dev)
|
|||
const struct mcux_ftm_config *config = dev->config->config_info;
|
||||
struct mcux_ftm_data *data = dev->driver_data;
|
||||
ftm_chnl_pwm_signal_param_t *channel = data->channel;
|
||||
struct device *clock_dev;
|
||||
ftm_config_t ftm_config;
|
||||
int i;
|
||||
|
||||
|
@ -121,6 +126,18 @@ static int mcux_ftm_init(struct device *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
clock_dev = device_get_binding(config->clock_name);
|
||||
if (clock_dev == NULL) {
|
||||
LOG_ERR("Could not get clock device");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (clock_control_get_rate(clock_dev, config->clock_subsys,
|
||||
&data->clock_freq)) {
|
||||
LOG_ERR("Could not get clock frequency");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < config->channel_count; i++) {
|
||||
channel->chnlNumber = i;
|
||||
channel->level = kFTM_LowTrue;
|
||||
|
@ -145,7 +162,9 @@ static const struct pwm_driver_api mcux_ftm_driver_api = {
|
|||
#ifdef CONFIG_PWM_0
|
||||
static const struct mcux_ftm_config mcux_ftm_config_0 = {
|
||||
.base = (FTM_Type *)DT_FTM_0_BASE_ADDRESS,
|
||||
.clock_source = kCLOCK_McgFixedFreqClk,
|
||||
.clock_name = DT_FTM_0_CLOCK_NAME,
|
||||
.clock_subsys =
|
||||
(clock_control_subsys_t) DT_FTM_0_CLOCK_SUBSYS,
|
||||
.ftm_clock_source = kFTM_FixedClock,
|
||||
.prescale = kFTM_Prescale_Divide_16,
|
||||
.channel_count = FSL_FEATURE_FTM_CHANNEL_COUNTn(FTM0),
|
||||
|
@ -163,7 +182,9 @@ DEVICE_AND_API_INIT(mcux_ftm_0, DT_FTM_0_NAME, &mcux_ftm_init,
|
|||
#ifdef CONFIG_PWM_1
|
||||
static const struct mcux_ftm_config mcux_ftm_config_1 = {
|
||||
.base = (FTM_Type *)DT_FTM_1_BASE_ADDRESS,
|
||||
.clock_source = kCLOCK_McgFixedFreqClk,
|
||||
.clock_name = DT_FTM_1_CLOCK_NAME,
|
||||
.clock_subsys =
|
||||
(clock_control_subsys_t) DT_FTM_1_CLOCK_SUBSYS,
|
||||
.ftm_clock_source = kFTM_FixedClock,
|
||||
.prescale = kFTM_Prescale_Divide_16,
|
||||
.channel_count = FSL_FEATURE_FTM_CHANNEL_COUNTn(FTM1),
|
||||
|
@ -181,7 +202,9 @@ DEVICE_AND_API_INIT(mcux_ftm_1, DT_FTM_1_NAME, &mcux_ftm_init,
|
|||
#ifdef CONFIG_PWM_2
|
||||
static const struct mcux_ftm_config mcux_ftm_config_2 = {
|
||||
.base = (FTM_Type *)DT_FTM_2_BASE_ADDRESS,
|
||||
.clock_source = kCLOCK_McgFixedFreqClk,
|
||||
.clock_name = DT_FTM_2_CLOCK_NAME,
|
||||
.clock_subsys =
|
||||
(clock_control_subsys_t) DT_FTM_2_CLOCK_SUBSYS,
|
||||
.ftm_clock_source = kFTM_FixedClock,
|
||||
.prescale = kFTM_Prescale_Divide_16,
|
||||
.channel_count = FSL_FEATURE_FTM_CHANNEL_COUNTn(FTM2),
|
||||
|
@ -199,7 +222,9 @@ DEVICE_AND_API_INIT(mcux_ftm_2, DT_FTM_2_NAME, &mcux_ftm_init,
|
|||
#ifdef CONFIG_PWM_3
|
||||
static const struct mcux_ftm_config mcux_ftm_config_3 = {
|
||||
.base = (FTM_Type *)DT_FTM_3_BASE_ADDRESS,
|
||||
.clock_source = kCLOCK_McgFixedFreqClk,
|
||||
.clock_name = DT_FTM_3_CLOCK_NAME,
|
||||
.clock_subsys =
|
||||
(clock_control_subsys_t) DT_FTM_3_CLOCK_SUBSYS,
|
||||
.ftm_clock_source = kFTM_FixedClock,
|
||||
.prescale = kFTM_Prescale_Divide_16,
|
||||
.channel_count = FSL_FEATURE_FTM_CHANNEL_COUNTn(FTM3),
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <arm/armv7-m.dtsi>
|
||||
#include <dt-bindings/clock/kinetis_sim.h>
|
||||
#include <dt-bindings/clock/kinetis_mcg.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/i2c/i2c.h>
|
||||
|
||||
|
@ -46,9 +47,11 @@
|
|||
};
|
||||
|
||||
mcg: clock-controller@40064000 {
|
||||
compatible = "nxp,k64f-mcg";
|
||||
compatible = "nxp,kinetis-mcg";
|
||||
reg = <0x40064000 0xd>;
|
||||
label = "MCG";
|
||||
system-clock-frequency = <120000000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
clock-controller@40065000 {
|
||||
|
@ -338,6 +341,7 @@
|
|||
compatible = "nxp,kinetis-ftm";
|
||||
reg = <0x40038000 0x98>;
|
||||
interrupts = <42 0>;
|
||||
clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>;
|
||||
label = "PWM_0";
|
||||
status = "disabled";
|
||||
#pwm-cells = <2>;
|
||||
|
@ -347,6 +351,7 @@
|
|||
compatible = "nxp,kinetis-ftm";
|
||||
reg = <0x40039000 0x98>;
|
||||
interrupts = <43 0>;
|
||||
clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>;
|
||||
label = "PWM_1";
|
||||
status = "disabled";
|
||||
#pwm-cells = <2>;
|
||||
|
@ -356,6 +361,7 @@
|
|||
compatible = "nxp,kinetis-ftm";
|
||||
reg = <0x4003a000 0x98>;
|
||||
interrupts = <44 0>;
|
||||
clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>;
|
||||
label = "PWM_2";
|
||||
status = "disabled";
|
||||
#pwm-cells = <2>;
|
||||
|
@ -365,6 +371,7 @@
|
|||
compatible = "nxp,kinetis-ftm";
|
||||
reg = <0x400b9000 0x98>;
|
||||
interrupts = <71 0>;
|
||||
clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>;
|
||||
label = "PWM_3";
|
||||
status = "disabled";
|
||||
#pwm-cells = <2>;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <arm/armv7-m.dtsi>
|
||||
#include <dt-bindings/clock/kinetis_sim.h>
|
||||
#include <dt-bindings/clock/kinetis_mcg.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/i2c/i2c.h>
|
||||
|
||||
|
@ -25,9 +26,11 @@
|
|||
soc {
|
||||
|
||||
mcg: clock-controller@40064000 {
|
||||
compatible = "nxp,k64f-mcg";
|
||||
compatible = "nxp,kinetis-mcg";
|
||||
reg = <0x40064000 0xd>;
|
||||
label = "MCG";
|
||||
system-clock-frequency = <48000000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
clock-controller@40065000 {
|
||||
|
@ -275,6 +278,7 @@
|
|||
compatible = "nxp,kinetis-ftm";
|
||||
reg = <0x40038000 0x98>;
|
||||
interrupts = <42 0>;
|
||||
clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>;
|
||||
label = "PWM_0";
|
||||
status = "disabled";
|
||||
#pwm-cells = <2>;
|
||||
|
@ -284,6 +288,7 @@
|
|||
compatible = "nxp,kinetis-ftm";
|
||||
reg = <0x40039000 0x98>;
|
||||
interrupts = <43 0>;
|
||||
clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>;
|
||||
label = "PWM_1";
|
||||
status = "disabled";
|
||||
#pwm-cells = <2>;
|
||||
|
@ -293,6 +298,7 @@
|
|||
compatible = "nxp,kinetis-ftm";
|
||||
reg = <0x4003a000 0x98>;
|
||||
interrupts = <44 0>;
|
||||
clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>;
|
||||
label = "PWM_2";
|
||||
status = "disabled";
|
||||
#pwm-cells = <2>;
|
||||
|
|
|
@ -31,6 +31,9 @@ if CLOCK_CONTROL
|
|||
config CLOCK_CONTROL_MCUX_SIM
|
||||
default y
|
||||
|
||||
config CLOCK_CONTROL_MCUX_MCG
|
||||
default y
|
||||
|
||||
endif # CLOCK_CONTROL
|
||||
|
||||
if PINMUX
|
||||
|
|
|
@ -77,10 +77,14 @@
|
|||
#define DT_FTM_3_IRQ DT_NXP_KINETIS_FTM_400B9000_IRQ_0
|
||||
#define DT_FTM_3_IRQ_PRI DT_NXP_KINETIS_FTM_400B9000_IRQ_0_PRIORITY
|
||||
#define DT_FTM_3_NAME DT_NXP_KINETIS_FTM_400B9000_LABEL
|
||||
#define DT_FTM_3_CLOCK_NAME DT_NXP_KINETIS_FTM_400B9000_CLOCK_CONTROLLER
|
||||
#define DT_FTM_3_CLOCK_SUBSYS DT_NXP_KINETIS_FTM_400B9000_CLOCK_NAME
|
||||
|
||||
#define DT_SIM_BASE_ADDRESS DT_NXP_KINETIS_SIM_40047000_BASE_ADDRESS
|
||||
#define DT_SIM_NAME DT_NXP_KINETIS_SIM_40047000_LABEL
|
||||
|
||||
#define DT_MCG_NAME DT_NXP_KINETIS_MCG_40064000_LABEL
|
||||
|
||||
#define CONFIG_I2C_0_NAME DT_NXP_KINETIS_I2C_40066000_LABEL
|
||||
#define DT_I2C_MCUX_0_BASE_ADDRESS DT_NXP_KINETIS_I2C_40066000_BASE_ADDRESS
|
||||
#define DT_I2C_MCUX_0_IRQ DT_NXP_KINETIS_I2C_40066000_IRQ_0
|
||||
|
|
|
@ -39,6 +39,9 @@ if CLOCK_CONTROL
|
|||
config CLOCK_CONTROL_MCUX_SIM
|
||||
default y
|
||||
|
||||
config CLOCK_CONTROL_MCUX_MCG
|
||||
default y
|
||||
|
||||
endif # CLOCK_CONTROL
|
||||
|
||||
if PINMUX
|
||||
|
|
|
@ -23,10 +23,14 @@
|
|||
#define DT_FTM_1_IRQ DT_NXP_KINETIS_FTM_40039000_IRQ_0
|
||||
#define DT_FTM_1_IRQ_PRI DT_NXP_KINETIS_FTM_40039000_IRQ_0_PRIORITY
|
||||
#define DT_FTM_1_NAME DT_NXP_KINETIS_FTM_40039000_LABEL
|
||||
#define DT_FTM_1_CLOCK_NAME DT_NXP_KINETIS_FTM_40039000_CLOCK_CONTROLLER
|
||||
#define DT_FTM_1_CLOCK_SUBSYS DT_NXP_KINETIS_FTM_40039000_CLOCK_NAME
|
||||
|
||||
#define DT_SIM_BASE_ADDRESS DT_NXP_KINETIS_SIM_40047000_BASE_ADDRESS
|
||||
#define DT_SIM_NAME DT_NXP_KINETIS_SIM_40047000_LABEL
|
||||
|
||||
#define DT_MCG_NAME DT_NXP_KINETIS_MCG_40064000_LABEL
|
||||
|
||||
#define DT_RTC_MCUX_0_BASE_ADDRESS DT_NXP_KINETIS_RTC_4003D000_BASE_ADDRESS
|
||||
#define DT_RTC_MCUX_0_IRQ_PRI DT_NXP_KINETIS_RTC_4003D000_IRQ_0_PRIORITY
|
||||
#define DT_RTC_MCUX_0_IRQ DT_NXP_KINETIS_RTC_4003D000_IRQ_0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue