Lines Matching +full:imx27 +full:- +full:pwm
1 // SPDX-License-Identifier: GPL-2.0
3 * simple driver for PWM (Pulse Width Modulator) controller
5 * Derived from pxa PWM driver by eric miao <eric.miao@marvell.com>
8 * - When disabled the output is driven to 0 independent of the configured
22 #include <linux/pwm.h>
25 #define MX3_PWMCR 0x00 /* PWM Control Register */
26 #define MX3_PWMSR 0x04 /* PWM Status Register */
27 #define MX3_PWMSAR 0x0C /* PWM Sample Register */
28 #define MX3_PWMPR 0x10 /* PWM Period Register */
73 #define MX3_PWMCR_PRESCALER_SET(x) FIELD_PREP(MX3_PWMCR_PRESCALER, (x) - 1)
102 ret = clk_prepare_enable(imx->clk_ipg); in pwm_imx27_clk_prepare_enable()
106 ret = clk_prepare_enable(imx->clk_per); in pwm_imx27_clk_prepare_enable()
108 clk_disable_unprepare(imx->clk_ipg); in pwm_imx27_clk_prepare_enable()
117 clk_disable_unprepare(imx->clk_per); in pwm_imx27_clk_disable_unprepare()
118 clk_disable_unprepare(imx->clk_ipg); in pwm_imx27_clk_disable_unprepare()
122 struct pwm_device *pwm, struct pwm_state *state) in pwm_imx27_get_state() argument
133 val = readl(imx->mmio_base + MX3_PWMCR); in pwm_imx27_get_state()
136 state->enabled = true; in pwm_imx27_get_state()
138 state->enabled = false; in pwm_imx27_get_state()
142 state->polarity = PWM_POLARITY_NORMAL; in pwm_imx27_get_state()
145 state->polarity = PWM_POLARITY_INVERSED; in pwm_imx27_get_state()
148 dev_warn(chip->dev, "can't set polarity, output disconnected"); in pwm_imx27_get_state()
152 pwm_clk = clk_get_rate(imx->clk_per); in pwm_imx27_get_state()
153 val = readl(imx->mmio_base + MX3_PWMPR); in pwm_imx27_get_state()
158 state->period = DIV_ROUND_UP_ULL(tmp, pwm_clk); in pwm_imx27_get_state()
161 * PWMSAR can be read only if PWM is enabled. If the PWM is disabled, in pwm_imx27_get_state()
164 if (state->enabled) in pwm_imx27_get_state()
165 val = readl(imx->mmio_base + MX3_PWMSAR); in pwm_imx27_get_state()
167 val = imx->duty_cycle; in pwm_imx27_get_state()
170 state->duty_cycle = DIV_ROUND_UP_ULL(tmp, pwm_clk); in pwm_imx27_get_state()
178 struct device *dev = chip->dev; in pwm_imx27_sw_reset()
182 writel(MX3_PWMCR_SWR, imx->mmio_base + MX3_PWMCR); in pwm_imx27_sw_reset()
185 cr = readl(imx->mmio_base + MX3_PWMCR); in pwm_imx27_sw_reset()
194 struct pwm_device *pwm) in pwm_imx27_wait_fifo_slot() argument
197 struct device *dev = chip->dev; in pwm_imx27_wait_fifo_slot()
202 sr = readl(imx->mmio_base + MX3_PWMSR); in pwm_imx27_wait_fifo_slot()
205 period_ms = DIV_ROUND_UP_ULL(pwm_get_period(pwm), in pwm_imx27_wait_fifo_slot()
209 sr = readl(imx->mmio_base + MX3_PWMSR); in pwm_imx27_wait_fifo_slot()
215 static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, in pwm_imx27_apply() argument
226 pwm_get_state(pwm, &cstate); in pwm_imx27_apply()
228 clkrate = clk_get_rate(imx->clk_per); in pwm_imx27_apply()
229 c = clkrate * state->period; in pwm_imx27_apply()
237 c = clkrate * state->duty_cycle; in pwm_imx27_apply()
242 * according to imx pwm RM, the real period value should be PERIOD in pwm_imx27_apply()
246 period_cycles -= 2; in pwm_imx27_apply()
251 * Wait for a free FIFO slot if the PWM is already enabled, and flush in pwm_imx27_apply()
252 * the FIFO if the PWM was disabled and is about to be enabled. in pwm_imx27_apply()
255 pwm_imx27_wait_fifo_slot(chip, pwm); in pwm_imx27_apply()
264 writel(duty_cycles, imx->mmio_base + MX3_PWMSAR); in pwm_imx27_apply()
265 writel(period_cycles, imx->mmio_base + MX3_PWMPR); in pwm_imx27_apply()
269 * MX3_PWMSAR register can't be read (i.e. when the PWM is disabled). in pwm_imx27_apply()
271 imx->duty_cycle = duty_cycles; in pwm_imx27_apply()
278 if (state->polarity == PWM_POLARITY_INVERSED) in pwm_imx27_apply()
282 if (state->enabled) in pwm_imx27_apply()
285 writel(cr, imx->mmio_base + MX3_PWMCR); in pwm_imx27_apply()
287 if (!state->enabled) in pwm_imx27_apply()
300 { .compatible = "fsl,imx27-pwm", },
311 imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); in pwm_imx27_probe()
313 return -ENOMEM; in pwm_imx27_probe()
317 imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); in pwm_imx27_probe()
318 if (IS_ERR(imx->clk_ipg)) { in pwm_imx27_probe()
319 int ret = PTR_ERR(imx->clk_ipg); in pwm_imx27_probe()
321 if (ret != -EPROBE_DEFER) in pwm_imx27_probe()
322 dev_err(&pdev->dev, in pwm_imx27_probe()
328 imx->clk_per = devm_clk_get(&pdev->dev, "per"); in pwm_imx27_probe()
329 if (IS_ERR(imx->clk_per)) { in pwm_imx27_probe()
330 int ret = PTR_ERR(imx->clk_per); in pwm_imx27_probe()
332 if (ret != -EPROBE_DEFER) in pwm_imx27_probe()
333 dev_err(&pdev->dev, in pwm_imx27_probe()
340 imx->chip.ops = &pwm_imx27_ops; in pwm_imx27_probe()
341 imx->chip.dev = &pdev->dev; in pwm_imx27_probe()
342 imx->chip.base = -1; in pwm_imx27_probe()
343 imx->chip.npwm = 1; in pwm_imx27_probe()
345 imx->chip.of_xlate = of_pwm_xlate_with_flags; in pwm_imx27_probe()
346 imx->chip.of_pwm_n_cells = 3; in pwm_imx27_probe()
348 imx->mmio_base = devm_platform_ioremap_resource(pdev, 0); in pwm_imx27_probe()
349 if (IS_ERR(imx->mmio_base)) in pwm_imx27_probe()
350 return PTR_ERR(imx->mmio_base); in pwm_imx27_probe()
356 /* keep clks on if pwm is running */ in pwm_imx27_probe()
357 pwmcr = readl(imx->mmio_base + MX3_PWMCR); in pwm_imx27_probe()
361 return pwmchip_add(&imx->chip); in pwm_imx27_probe()
370 return pwmchip_remove(&imx->chip); in pwm_imx27_remove()
375 .name = "pwm-imx27",