diff --git a/drivers/pwm/pwm_mchp_xec.c b/drivers/pwm/pwm_mchp_xec.c index 88aa29937eb..8dd95e003b8 100644 --- a/drivers/pwm/pwm_mchp_xec.c +++ b/drivers/pwm/pwm_mchp_xec.c @@ -1,22 +1,30 @@ -/* pwm_mchp_xec.c - Microchip XEC PWM driver */ - -#define DT_DRV_COMPAT microchip_xec_pwm - /* * Copyright (c) 2019 Intel Corporation + * Copyright (c) 2022 Microchip Technololgy Inc. * * SPDX-License-Identifier: Apache-2.0 */ -#include -LOG_MODULE_REGISTER(pwm_mchp_xec, CONFIG_PWM_LOG_LEVEL); +#define DT_DRV_COMPAT microchip_xec_pwm -#include -#include #include +#include +#include +#ifdef CONFIG_SOC_SERIES_MEC172X +#include +#include +#endif +#include +#include +#include +#include +#include #include +#include +LOG_MODULE_REGISTER(pwm_mchp_xec, CONFIG_PWM_LOG_LEVEL); + /* Minimal on/off are 1 & 1 both are incremented, so 4. * 0 cannot be set (used for full low/high output) so a * combination of on_off of 2 is not possible. @@ -43,18 +51,11 @@ LOG_MODULE_REGISTER(pwm_mchp_xec, CONFIG_PWM_LOG_LEVEL); #define XEC_PWM_FREQ_LIMIT 1 /* 0.1hz * XEC_PWM_FREQ_PF */ struct pwm_xec_config { - uint32_t base_address; + struct pwm_regs * const regs; + uint8_t pcr_idx; + uint8_t pcr_pos; }; -#define PWM_XEC_REG_BASE(_dev) \ - ((PWM_Type *) \ - ((const struct pwm_xec_config * const) \ - _dev->config)->base_address) - -#define PWM_XEC_CONFIG(_dev) \ - (((const struct pwm_xec_config * const) \ - _dev->config)) - struct xec_params { uint32_t on; uint32_t off; @@ -63,7 +64,7 @@ struct xec_params { #define NUM_DIV_ELEMS 16 -uint32_t max_freq_high_on_div[NUM_DIV_ELEMS] = { +static const uint32_t max_freq_high_on_div[NUM_DIV_ELEMS] = { 48000000, 24000000, 16000000, @@ -82,7 +83,7 @@ uint32_t max_freq_high_on_div[NUM_DIV_ELEMS] = { 3000000 }; -uint32_t max_freq_low_on_div[NUM_DIV_ELEMS] = { +static const uint32_t max_freq_low_on_div[NUM_DIV_ELEMS] = { 100000, 50000, 33333, @@ -106,7 +107,7 @@ static uint32_t xec_compute_frequency(uint32_t clk, uint32_t on, uint32_t off) return ((clk * XEC_PWM_FREQ_PF)/((on + 1) + (off + 1))); } -static uint16_t xec_select_div(uint32_t freq, uint32_t max_freq[16]) +static uint16_t xec_select_div(uint32_t freq, const uint32_t max_freq[16]) { uint8_t i; @@ -147,9 +148,9 @@ static uint32_t xec_compute_dc(uint32_t on, uint32_t off) } static uint16_t xec_compare_div_on_off(uint32_t target_freq, uint32_t dc, - uint32_t max_freq[16], - uint8_t div_a, uint8_t div_b, - uint32_t *on_a, uint32_t *off_a) + const uint32_t max_freq[16], + uint8_t div_a, uint8_t div_b, + uint32_t *on_a, uint32_t *off_a) { uint32_t freq_a, freq_b, on_b, off_b; @@ -180,8 +181,8 @@ static uint16_t xec_compare_div_on_off(uint32_t target_freq, uint32_t dc, } static uint8_t xec_select_best_div_on_off(uint32_t target_freq, uint32_t dc, - uint32_t max_freq[16], - uint32_t *on, uint32_t *off) + const uint32_t max_freq[16], + uint32_t *on, uint32_t *off) { int div_comp; uint8_t div; @@ -237,12 +238,13 @@ static void xec_compute_and_set_parameters(const struct device *dev, uint32_t target_freq, uint32_t on, uint32_t off) { - PWM_Type *pwm_regs = PWM_XEC_REG_BASE(dev); + const struct pwm_xec_config * const cfg = dev->config; + struct pwm_regs * const regs = cfg->regs; bool compute_high, compute_low; struct xec_params hc_params; struct xec_params lc_params; struct xec_params *params; - uint32_t dc, reg; + uint32_t dc, cfgval; dc = xec_compute_dc(on, off); @@ -287,30 +289,31 @@ static void xec_compute_and_set_parameters(const struct device *dev, lc_params.div = UINT8_MAX; } done: - pwm_regs->CONFIG &= ~MCHP_PWM_CFG_ENABLE; + regs->CONFIG &= ~MCHP_PWM_CFG_ENABLE; - reg = pwm_regs->CONFIG; + cfgval = regs->CONFIG; params = xec_compare_params(target_freq, &hc_params, &lc_params); if (params == &hc_params) { - reg |= MCHP_PWM_CFG_CLK_SEL_48M; + cfgval |= MCHP_PWM_CFG_CLK_SEL_48M; } else { - reg |= MCHP_PWM_CFG_CLK_SEL_100K; + cfgval |= MCHP_PWM_CFG_CLK_SEL_100K; } - pwm_regs->COUNT_ON = params->on; - pwm_regs->COUNT_OFF = params->off; - reg |= MCHP_PWM_CFG_CLK_PRE_DIV(params->div); - reg |= MCHP_PWM_CFG_ENABLE; + regs->COUNT_ON = params->on; + regs->COUNT_OFF = params->off; + cfgval |= MCHP_PWM_CFG_CLK_PRE_DIV(params->div); + cfgval |= MCHP_PWM_CFG_ENABLE; - pwm_regs->CONFIG = reg; + regs->CONFIG = cfgval; } static int pwm_xec_pin_set(const struct device *dev, uint32_t pwm, uint32_t period_cycles, uint32_t pulse_cycles, pwm_flags_t flags) { - PWM_Type *pwm_regs = PWM_XEC_REG_BASE(dev); + const struct pwm_xec_config * const cfg = dev->config; + struct pwm_regs * const regs = cfg->regs; uint32_t target_freq; uint32_t on, off; @@ -337,13 +340,13 @@ static int pwm_xec_pin_set(const struct device *dev, uint32_t pwm, } if ((pulse_cycles == 0U) && (period_cycles == 0U)) { - pwm_regs->CONFIG &= ~MCHP_PWM_CFG_ENABLE; + regs->CONFIG &= ~MCHP_PWM_CFG_ENABLE; } else if ((pulse_cycles == 0U) && (period_cycles > 0U)) { - pwm_regs->COUNT_ON = 0; - pwm_regs->COUNT_OFF = 1; + regs->COUNT_ON = 0; + regs->COUNT_OFF = 1; } else if ((pulse_cycles > 0U) && (period_cycles == 0U)) { - pwm_regs->COUNT_ON = 1; - pwm_regs->COUNT_OFF = 0; + regs->COUNT_ON = 1; + regs->COUNT_OFF = 0; } else { xec_compute_and_set_parameters(dev, target_freq, on, off); } @@ -370,6 +373,11 @@ static int pwm_xec_get_cycles_per_sec(const struct device *dev, uint32_t pwm, return 0; } +static const struct pwm_driver_api pwm_xec_driver_api = { + .pin_set = pwm_xec_pin_set, + .get_cycles_per_sec = pwm_xec_get_cycles_per_sec, +}; + static int pwm_xec_init(const struct device *dev) { ARG_UNUSED(dev); @@ -377,23 +385,22 @@ static int pwm_xec_init(const struct device *dev) return 0; } -static struct pwm_driver_api pwm_xec_api = { - .pin_set = pwm_xec_pin_set, - .get_cycles_per_sec = pwm_xec_get_cycles_per_sec -}; +#define XEC_PWM_CONFIG(inst) \ + static struct pwm_xec_config pwm_xec_config_##inst = { \ + .regs = (struct pwm_regs * const)DT_INST_REG_ADDR(inst), \ + .pcr_idx = (uint8_t)DT_INST_PROP_BY_IDX(inst, pcrs, 0), \ + .pcr_pos = (uint8_t)DT_INST_PROP_BY_IDX(inst, pcrs, 1), \ + }; -#define XEC_INST_INIT(inst) \ - static struct pwm_xec_config pwm_xec_dev_config_##inst = { \ - .base_address = DT_INST_REG_ADDR(inst) \ - }; \ +#define XEC_PWM_DEVICE_INIT(index) \ \ - DEVICE_DT_INST_DEFINE(inst, \ - pwm_xec_init, \ - NULL, \ - NULL, \ - &pwm_xec_dev_config_##inst, \ - POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ - &pwm_xec_api); + XEC_PWM_CONFIG(index); \ + \ + DEVICE_DT_INST_DEFINE(index, &pwm_xec_init, \ + NULL, \ + NULL, \ + &pwm_xec_config_##index, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &pwm_xec_driver_api); -DT_INST_FOREACH_STATUS_OKAY(XEC_INST_INIT) +DT_INST_FOREACH_STATUS_OKAY(XEC_PWM_DEVICE_INIT) diff --git a/dts/arm/microchip/mec1501hsz.dtsi b/dts/arm/microchip/mec1501hsz.dtsi index 564ab0b09a4..c116ba132d7 100644 --- a/dts/arm/microchip/mec1501hsz.dtsi +++ b/dts/arm/microchip/mec1501hsz.dtsi @@ -341,6 +341,7 @@ pwm0: pwm@40005800 { compatible = "microchip,xec-pwm"; reg = <0x40005800 0x20>; + pcrs = <1 4>; label = "PWM_0"; status = "disabled"; #pwm-cells = <1>; @@ -348,6 +349,7 @@ pwm1: pwm@40005810 { compatible = "microchip,xec-pwm"; reg = <0x40005810 0x20>; + pcrs = <1 20>; label = "PWM_1"; status = "disabled"; #pwm-cells = <1>; @@ -355,6 +357,7 @@ pwm2: pwm@40005820 { compatible = "microchip,xec-pwm"; reg = <0x40005820 0x20>; + pcrs = <1 21>; label = "PWM_2"; status = "disabled"; #pwm-cells = <1>; @@ -362,6 +365,7 @@ pwm3: pwm@40005830 { compatible = "microchip,xec-pwm"; reg = <0x40005830 0x20>; + pcrs = <1 22>; label = "PWM_3"; status = "disabled"; #pwm-cells = <1>; @@ -369,6 +373,7 @@ pwm4: pwm@40005840 { compatible = "microchip,xec-pwm"; reg = <0x40005840 0x20>; + pcrs = <1 23>; label = "PWM_4"; status = "disabled"; #pwm-cells = <1>; @@ -376,6 +381,7 @@ pwm5: pwm@40005850 { compatible = "microchip,xec-pwm"; reg = <0x40005850 0x20>; + pcrs = <1 24>; label = "PWM_5"; status = "disabled"; #pwm-cells = <1>; @@ -383,6 +389,7 @@ pwm6: pwm@40005860 { compatible = "microchip,xec-pwm"; reg = <0x40005860 0x20>; + pcrs = <1 25>; label = "PWM_6"; status = "disabled"; #pwm-cells = <1>; @@ -390,6 +397,7 @@ pwm7: pwm@40005870 { compatible = "microchip,xec-pwm"; reg = <0x40005870 0x20>; + pcrs = <1 26>; label = "PWM_7"; status = "disabled"; #pwm-cells = <1>; @@ -397,6 +405,7 @@ pwm8: pwm@40005880 { compatible = "microchip,xec-pwm"; reg = <0x40005880 0x20>; + pcrs = <1 27>; label = "PWM_8"; status = "disabled"; #pwm-cells = <1>; diff --git a/dts/arm/microchip/mec172xnsz.dtsi b/dts/arm/microchip/mec172xnsz.dtsi index 024342ca748..f68dac5cf3f 100644 --- a/dts/arm/microchip/mec172xnsz.dtsi +++ b/dts/arm/microchip/mec172xnsz.dtsi @@ -587,6 +587,7 @@ status = "disabled"; }; pwm0: pwm@40005800 { + compatible = "microchip,xec-pwm"; reg = <0x40005800 0x20>; pcrs = <1 4>; label = "PWM_0"; @@ -594,6 +595,7 @@ #pwm-cells = <1>; }; pwm1: pwm@40005810 { + compatible = "microchip,xec-pwm"; reg = <0x40005810 0x20>; pcrs = <1 20>; label = "PWM_1"; @@ -601,6 +603,7 @@ #pwm-cells = <1>; }; pwm2: pwm@40005820 { + compatible = "microchip,xec-pwm"; reg = <0x40005820 0x20>; pcrs = <1 21>; label = "PWM_2"; @@ -608,6 +611,7 @@ #pwm-cells = <1>; }; pwm3: pwm@40005830 { + compatible = "microchip,xec-pwm"; reg = <0x40005830 0x20>; pcrs = <1 22>; label = "PWM_3"; @@ -615,6 +619,7 @@ #pwm-cells = <1>; }; pwm4: pwm@40005840 { + compatible = "microchip,xec-pwm"; reg = <0x40005840 0x20>; pcrs = <1 23>; label = "PWM_4"; @@ -622,6 +627,7 @@ #pwm-cells = <1>; }; pwm5: pwm@40005850 { + compatible = "microchip,xec-pwm"; reg = <0x40005850 0x20>; pcrs = <1 24>; label = "PWM_5"; @@ -629,6 +635,7 @@ #pwm-cells = <1>; }; pwm6: pwm@40005860 { + compatible = "microchip,xec-pwm"; reg = <0x40005860 0x20>; pcrs = <1 25>; label = "PWM_6"; @@ -636,6 +643,7 @@ #pwm-cells = <1>; }; pwm7: pwm@40005870 { + compatible = "microchip,xec-pwm"; reg = <0x40005870 0x20>; pcrs = <1 26>; label = "PWM_7"; @@ -643,6 +651,7 @@ #pwm-cells = <1>; }; pwm8: pwm@40005880 { + compatible = "microchip,xec-pwm"; reg = <0x40005880 0x20>; pcrs = <1 27>; label = "PWM_8"; diff --git a/dts/bindings/pwm/microchip,xec-pwm.yaml b/dts/bindings/pwm/microchip,xec-pwm.yaml index 630b4a31290..623d3045d05 100644 --- a/dts/bindings/pwm/microchip,xec-pwm.yaml +++ b/dts/bindings/pwm/microchip,xec-pwm.yaml @@ -13,3 +13,12 @@ properties: label: required: true + + pcrs: + type: array + required: true + description: PWM PCR register index and bit position + +pcr-cells: + - regidx + - bitpos