Lines Matching +full:pwm +full:- +full:active +full:- +full:state

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ECAP PWM driver
5 * Copyright (C) 2012 Texas Instruments, Inc. - https://www.ti.com/
14 #include <linux/pwm.h>
50 static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, in ecap_pwm_config() argument
58 c = pc->clk_rate; in ecap_pwm_config()
67 c = pc->clk_rate; in ecap_pwm_config()
73 pm_runtime_get_sync(pc->chip.dev); in ecap_pwm_config()
75 value = readw(pc->mmio_base + ECCTL2); in ecap_pwm_config()
80 writew(value, pc->mmio_base + ECCTL2); in ecap_pwm_config()
83 /* Update active registers if not running */ in ecap_pwm_config()
84 writel(duty_cycles, pc->mmio_base + CAP2); in ecap_pwm_config()
85 writel(period_cycles, pc->mmio_base + CAP1); in ecap_pwm_config()
89 * compare values. This helps current PWM period to in ecap_pwm_config()
92 writel(duty_cycles, pc->mmio_base + CAP4); in ecap_pwm_config()
93 writel(period_cycles, pc->mmio_base + CAP3); in ecap_pwm_config()
97 value = readw(pc->mmio_base + ECCTL2); in ecap_pwm_config()
100 writew(value, pc->mmio_base + ECCTL2); in ecap_pwm_config()
103 pm_runtime_put_sync(pc->chip.dev); in ecap_pwm_config()
108 static int ecap_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, in ecap_pwm_set_polarity() argument
114 pm_runtime_get_sync(pc->chip.dev); in ecap_pwm_set_polarity()
116 value = readw(pc->mmio_base + ECCTL2); in ecap_pwm_set_polarity()
119 /* Duty cycle defines LOW period of PWM */ in ecap_pwm_set_polarity()
122 /* Duty cycle defines HIGH period of PWM */ in ecap_pwm_set_polarity()
125 writew(value, pc->mmio_base + ECCTL2); in ecap_pwm_set_polarity()
127 pm_runtime_put_sync(pc->chip.dev); in ecap_pwm_set_polarity()
132 static int ecap_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) in ecap_pwm_enable() argument
137 /* Leave clock enabled on enabling PWM */ in ecap_pwm_enable()
138 pm_runtime_get_sync(pc->chip.dev); in ecap_pwm_enable()
144 value = readw(pc->mmio_base + ECCTL2); in ecap_pwm_enable()
146 writew(value, pc->mmio_base + ECCTL2); in ecap_pwm_enable()
151 static void ecap_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) in ecap_pwm_disable() argument
160 value = readw(pc->mmio_base + ECCTL2); in ecap_pwm_disable()
162 writew(value, pc->mmio_base + ECCTL2); in ecap_pwm_disable()
164 /* Disable clock on PWM disable */ in ecap_pwm_disable()
165 pm_runtime_put_sync(pc->chip.dev); in ecap_pwm_disable()
168 static int ecap_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, in ecap_pwm_apply() argument
169 const struct pwm_state *state) in ecap_pwm_apply() argument
172 int enabled = pwm->state.enabled; in ecap_pwm_apply()
174 if (state->polarity != pwm->state.polarity) { in ecap_pwm_apply()
177 ecap_pwm_disable(chip, pwm); in ecap_pwm_apply()
181 err = ecap_pwm_set_polarity(chip, pwm, state->polarity); in ecap_pwm_apply()
186 if (!state->enabled) { in ecap_pwm_apply()
188 ecap_pwm_disable(chip, pwm); in ecap_pwm_apply()
192 if (state->period > NSEC_PER_SEC) in ecap_pwm_apply()
193 return -ERANGE; in ecap_pwm_apply()
195 err = ecap_pwm_config(chip, pwm, state->duty_cycle, in ecap_pwm_apply()
196 state->period, enabled); in ecap_pwm_apply()
201 return ecap_pwm_enable(chip, pwm); in ecap_pwm_apply()
212 { .compatible = "ti,am3352-ecap" },
213 { .compatible = "ti,am33xx-ecap" },
220 struct device_node *np = pdev->dev.of_node; in ecap_pwm_probe()
225 pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); in ecap_pwm_probe()
227 return -ENOMEM; in ecap_pwm_probe()
229 clk = devm_clk_get(&pdev->dev, "fck"); in ecap_pwm_probe()
231 if (of_device_is_compatible(np, "ti,am33xx-ecap")) { in ecap_pwm_probe()
232 dev_warn(&pdev->dev, "Binding is obsolete.\n"); in ecap_pwm_probe()
233 clk = devm_clk_get(pdev->dev.parent, "fck"); in ecap_pwm_probe()
238 dev_err(&pdev->dev, "failed to get clock\n"); in ecap_pwm_probe()
242 pc->clk_rate = clk_get_rate(clk); in ecap_pwm_probe()
243 if (!pc->clk_rate) { in ecap_pwm_probe()
244 dev_err(&pdev->dev, "failed to get clock rate\n"); in ecap_pwm_probe()
245 return -EINVAL; in ecap_pwm_probe()
248 pc->chip.dev = &pdev->dev; in ecap_pwm_probe()
249 pc->chip.ops = &ecap_pwm_ops; in ecap_pwm_probe()
250 pc->chip.npwm = 1; in ecap_pwm_probe()
252 pc->mmio_base = devm_platform_ioremap_resource(pdev, 0); in ecap_pwm_probe()
253 if (IS_ERR(pc->mmio_base)) in ecap_pwm_probe()
254 return PTR_ERR(pc->mmio_base); in ecap_pwm_probe()
256 ret = devm_pwmchip_add(&pdev->dev, &pc->chip); in ecap_pwm_probe()
258 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); in ecap_pwm_probe()
263 pm_runtime_enable(&pdev->dev); in ecap_pwm_probe()
270 pm_runtime_disable(&pdev->dev); in ecap_pwm_remove()
278 pm_runtime_get_sync(pc->chip.dev); in ecap_pwm_save_context()
279 pc->ctx.ecctl2 = readw(pc->mmio_base + ECCTL2); in ecap_pwm_save_context()
280 pc->ctx.cap4 = readl(pc->mmio_base + CAP4); in ecap_pwm_save_context()
281 pc->ctx.cap3 = readl(pc->mmio_base + CAP3); in ecap_pwm_save_context()
282 pm_runtime_put_sync(pc->chip.dev); in ecap_pwm_save_context()
287 writel(pc->ctx.cap3, pc->mmio_base + CAP3); in ecap_pwm_restore_context()
288 writel(pc->ctx.cap4, pc->mmio_base + CAP4); in ecap_pwm_restore_context()
289 writew(pc->ctx.ecctl2, pc->mmio_base + ECCTL2); in ecap_pwm_restore_context()
295 struct pwm_device *pwm = pc->chip.pwms; in ecap_pwm_suspend() local
299 /* Disable explicitly if PWM is running */ in ecap_pwm_suspend()
300 if (pwm_is_enabled(pwm)) in ecap_pwm_suspend()
309 struct pwm_device *pwm = pc->chip.pwms; in ecap_pwm_resume() local
311 /* Enable explicitly if PWM was running */ in ecap_pwm_resume()
312 if (pwm_is_enabled(pwm)) in ecap_pwm_resume()
333 MODULE_DESCRIPTION("ECAP PWM driver");