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

1 // SPDX-License-Identifier: GPL-2.0
58 return readl_relaxed(spc->base + offset); in sprd_pwm_read()
66 writel_relaxed(val, spc->base + offset); in sprd_pwm_write()
74 struct sprd_pwm_chn *chn = &spc->chn[pwm->hwpwm]; in sprd_pwm_get_state()
75 u32 val, duty, prescale; in sprd_pwm_get_state() local
83 ret = clk_bulk_prepare_enable(SPRD_PWM_CHN_CLKS_NUM, chn->clks); in sprd_pwm_get_state()
85 dev_err(spc->dev, "failed to enable pwm%u clocks\n", in sprd_pwm_get_state()
86 pwm->hwpwm); in sprd_pwm_get_state()
90 val = sprd_pwm_read(spc, pwm->hwpwm, SPRD_PWM_ENABLE); in sprd_pwm_get_state()
92 state->enabled = true; in sprd_pwm_get_state()
94 state->enabled = false; in sprd_pwm_get_state()
99 * The duty cycle length is (PRESCALE + 1) * DUTY counter steps. in sprd_pwm_get_state()
102 * duty_ns = NSEC_PER_SEC * (prescale + 1) * duty / clk_rate in sprd_pwm_get_state()
104 val = sprd_pwm_read(spc, pwm->hwpwm, SPRD_PWM_PRESCALE); in sprd_pwm_get_state()
107 state->period = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate); in sprd_pwm_get_state()
109 val = sprd_pwm_read(spc, pwm->hwpwm, SPRD_PWM_DUTY); in sprd_pwm_get_state()
110 duty = val & SPRD_PWM_DUTY_MSK; in sprd_pwm_get_state()
111 tmp = (prescale + 1) * NSEC_PER_SEC * duty; in sprd_pwm_get_state()
112 state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate); in sprd_pwm_get_state()
113 state->polarity = PWM_POLARITY_NORMAL; in sprd_pwm_get_state()
116 if (!state->enabled) in sprd_pwm_get_state()
117 clk_bulk_disable_unprepare(SPRD_PWM_CHN_CLKS_NUM, chn->clks); in sprd_pwm_get_state()
125 struct sprd_pwm_chn *chn = &spc->chn[pwm->hwpwm]; in sprd_pwm_config()
126 u32 prescale, duty; in sprd_pwm_config() local
132 * The duty cycle length is (PRESCALE + 1) * DUTY counter steps. in sprd_pwm_config()
139 duty = duty_ns * SPRD_PWM_MOD_MAX / period_ns; in sprd_pwm_config()
141 tmp = (u64)chn->clk_rate * period_ns; in sprd_pwm_config()
143 prescale = DIV_ROUND_CLOSEST_ULL(tmp, SPRD_PWM_MOD_MAX) - 1; in sprd_pwm_config()
148 * Note: Writing DUTY triggers the hardware to actually apply the in sprd_pwm_config()
149 * values written to MOD and DUTY to the output, so must keep writing in sprd_pwm_config()
150 * DUTY last. in sprd_pwm_config()
155 sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_PRESCALE, prescale); in sprd_pwm_config()
156 sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_MOD, SPRD_PWM_MOD_MAX); in sprd_pwm_config()
157 sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_DUTY, duty); in sprd_pwm_config()
167 struct sprd_pwm_chn *chn = &spc->chn[pwm->hwpwm]; in sprd_pwm_apply()
168 struct pwm_state *cstate = &pwm->state; in sprd_pwm_apply()
171 if (state->polarity != PWM_POLARITY_NORMAL) in sprd_pwm_apply()
172 return -EINVAL; in sprd_pwm_apply()
174 if (state->enabled) { in sprd_pwm_apply()
175 if (!cstate->enabled) { in sprd_pwm_apply()
181 chn->clks); in sprd_pwm_apply()
183 dev_err(spc->dev, in sprd_pwm_apply()
185 pwm->hwpwm); in sprd_pwm_apply()
190 ret = sprd_pwm_config(spc, pwm, state->duty_cycle, in sprd_pwm_apply()
191 state->period); in sprd_pwm_apply()
195 sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_ENABLE, 1); in sprd_pwm_apply()
196 } else if (cstate->enabled) { in sprd_pwm_apply()
202 sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_ENABLE, 0); in sprd_pwm_apply()
204 clk_bulk_disable_unprepare(SPRD_PWM_CHN_CLKS_NUM, chn->clks); in sprd_pwm_apply()
222 struct sprd_pwm_chn *chn = &spc->chn[i]; in sprd_pwm_clk_init()
226 chn->clks[j].id = in sprd_pwm_clk_init()
229 ret = devm_clk_bulk_get(spc->dev, SPRD_PWM_CHN_CLKS_NUM, in sprd_pwm_clk_init()
230 chn->clks); in sprd_pwm_clk_init()
232 if (ret == -ENOENT) in sprd_pwm_clk_init()
235 return dev_err_probe(spc->dev, ret, in sprd_pwm_clk_init()
239 clk_pwm = chn->clks[SPRD_PWM_CHN_OUTPUT_CLK].clk; in sprd_pwm_clk_init()
240 chn->clk_rate = clk_get_rate(clk_pwm); in sprd_pwm_clk_init()
244 dev_err(spc->dev, "no available PWM channels\n"); in sprd_pwm_clk_init()
245 return -ENODEV; in sprd_pwm_clk_init()
248 spc->num_pwms = i; in sprd_pwm_clk_init()
258 spc = devm_kzalloc(&pdev->dev, sizeof(*spc), GFP_KERNEL); in sprd_pwm_probe()
260 return -ENOMEM; in sprd_pwm_probe()
262 spc->base = devm_platform_ioremap_resource(pdev, 0); in sprd_pwm_probe()
263 if (IS_ERR(spc->base)) in sprd_pwm_probe()
264 return PTR_ERR(spc->base); in sprd_pwm_probe()
266 spc->dev = &pdev->dev; in sprd_pwm_probe()
273 spc->chip.dev = &pdev->dev; in sprd_pwm_probe()
274 spc->chip.ops = &sprd_pwm_ops; in sprd_pwm_probe()
275 spc->chip.npwm = spc->num_pwms; in sprd_pwm_probe()
277 ret = pwmchip_add(&spc->chip); in sprd_pwm_probe()
279 dev_err(&pdev->dev, "failed to add PWM chip\n"); in sprd_pwm_probe()
288 pwmchip_remove(&spc->chip); in sprd_pwm_remove()
292 { .compatible = "sprd,ums512-pwm", },
299 .name = "sprd-pwm",