Lines Matching +full:duty +full:- +full:cycle

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2017-2025 Loongson Technology Corporation Limited.
8 …* Reference Manual: https://loongson.github.io/LoongArch-Documentation/Loongson-7A1000-usermanual-
15 * - If both DUTY and PERIOD are set to 0, the output is a constant low signal.
16 * - When disabled the output is driven to 0 independent of the configured
18 * - If the register is reconfigured while PWM is running, it does not complete
20 * - Disabling the PWM stops the output immediately (without waiting for current
48 #define LOONGSON_PWM_CTRL_REG_INVERT BIT(9) /* Output flip-flop Enable Bit */
49 #define LOONGSON_PWM_CTRL_REG_DZONE BIT(10) /* Anti-dead Zone Enable Bit */
67 return readl(ddata->base + offset); in pwm_loongson_readl()
73 writel(val, ddata->base + offset); in pwm_loongson_writel()
85 /* Duty cycle defines LOW period of PWM */ in pwm_loongson_set_polarity()
88 /* Duty cycle defines HIGH period of PWM */ in pwm_loongson_set_polarity()
121 u64 duty, period; in pwm_loongson_config() local
124 /* duty = duty_ns * ddata->clk_rate / NSEC_PER_SEC */ in pwm_loongson_config()
125 duty = mul_u64_u64_div_u64(duty_ns, ddata->clk_rate, NSEC_PER_SEC); in pwm_loongson_config()
126 if (duty > U32_MAX) in pwm_loongson_config()
127 duty = U32_MAX; in pwm_loongson_config()
129 /* period = period_ns * ddata->clk_rate / NSEC_PER_SEC */ in pwm_loongson_config()
130 period = mul_u64_u64_div_u64(period_ns, ddata->clk_rate, NSEC_PER_SEC); in pwm_loongson_config()
134 pwm_loongson_writel(ddata, duty, LOONGSON_PWM_REG_DUTY); in pwm_loongson_config()
144 bool enabled = pwm->state.enabled; in pwm_loongson_apply()
146 if (!state->enabled) { in pwm_loongson_apply()
152 ret = pwm_loongson_set_polarity(chip, pwm, state->polarity); in pwm_loongson_apply()
156 ret = pwm_loongson_config(chip, pwm, state->duty_cycle, state->period); in pwm_loongson_apply()
160 if (!enabled && state->enabled) in pwm_loongson_apply()
169 u32 duty, period, ctrl; in pwm_loongson_get_state() local
172 duty = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_DUTY); in pwm_loongson_get_state()
176 /* duty & period have a max of 2^32, so we can't overflow */ in pwm_loongson_get_state()
177 state->duty_cycle = DIV64_U64_ROUND_UP((u64)duty * NSEC_PER_SEC, ddata->clk_rate); in pwm_loongson_get_state()
178 state->period = DIV64_U64_ROUND_UP((u64)period * NSEC_PER_SEC, ddata->clk_rate); in pwm_loongson_get_state()
179 state->polarity = (ctrl & LOONGSON_PWM_CTRL_REG_INVERT) ? PWM_POLARITY_INVERSED : in pwm_loongson_get_state()
181 state->enabled = (ctrl & LOONGSON_PWM_CTRL_REG_EN) ? true : false; in pwm_loongson_get_state()
196 struct device *dev = &pdev->dev; in pwm_loongson_probe()
203 ddata->base = devm_platform_ioremap_resource(pdev, 0); in pwm_loongson_probe()
204 if (IS_ERR(ddata->base)) in pwm_loongson_probe()
205 return PTR_ERR(ddata->base); in pwm_loongson_probe()
207 ddata->clk = devm_clk_get_optional_enabled(dev, NULL); in pwm_loongson_probe()
208 if (IS_ERR(ddata->clk)) in pwm_loongson_probe()
209 return dev_err_probe(dev, PTR_ERR(ddata->clk), in pwm_loongson_probe()
211 if (ddata->clk) { in pwm_loongson_probe()
212 ret = devm_clk_rate_exclusive_get(dev, ddata->clk); in pwm_loongson_probe()
217 ddata->clk_rate = clk_get_rate(ddata->clk); in pwm_loongson_probe()
218 if (!ddata->clk_rate) in pwm_loongson_probe()
219 return dev_err_probe(dev, -EINVAL, in pwm_loongson_probe()
222 ddata->clk_rate = LOONGSON_PWM_FREQ_DEFAULT; in pwm_loongson_probe()
226 if (ddata->clk_rate > NSEC_PER_SEC) in pwm_loongson_probe()
227 return dev_err_probe(dev, -EINVAL, "PWM clock out of range\n"); in pwm_loongson_probe()
229 chip->ops = &pwm_loongson_ops; in pwm_loongson_probe()
230 chip->atomic = true; in pwm_loongson_probe()
244 struct pwm_device *pwm = &chip->pwms[0]; in pwm_loongson_suspend()
246 if (pwm->state.enabled) in pwm_loongson_suspend()
247 return -EBUSY; in pwm_loongson_suspend()
249 clk_disable_unprepare(ddata->clk); in pwm_loongson_suspend()
259 return clk_prepare_enable(ddata->clk); in pwm_loongson_resume()
266 { .compatible = "loongson,ls7a-pwm" },
280 .name = "loongson-pwm",