Lines Matching +full:clk +full:- +full:pwm

1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/pwm/pwm-pxa.c
5 * simple driver for PWM (Pulse Width Modulator) controller
7 * 2008-02-13 initial version
10 * Links to reference manuals for some of the supported PWM chips can be found
14 * - When PWM is stopped, the current PWM period stops abruptly at the next
24 #include <linux/clk.h>
26 #include <linux/pwm.h>
34 /* PWM has_secondary_pwm? */
35 { "pxa25x-pwm", 0 },
36 { "pxa27x-pwm", HAS_SECONDARY_PWM },
37 { "pxa168-pwm", 0 },
38 { "pxa910-pwm", 0 },
43 /* PWM registers and bits definitions */
55 struct clk *clk; member
68 static int pxa_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, in pxa_pwm_config() argument
76 offset = pwm->hwpwm ? 0x10 : 0; in pxa_pwm_config()
78 c = clk_get_rate(pc->clk); in pxa_pwm_config()
85 prescale = (period_cycles - 1) / 1024; in pxa_pwm_config()
86 pv = period_cycles / (prescale + 1) - 1; in pxa_pwm_config()
89 return -EINVAL; in pxa_pwm_config()
96 writel(prescale | PWMCR_SD, pc->mmio_base + offset + PWMCR); in pxa_pwm_config()
97 writel(dc, pc->mmio_base + offset + PWMDCR); in pxa_pwm_config()
98 writel(pv, pc->mmio_base + offset + PWMPCR); in pxa_pwm_config()
103 static int pxa_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, in pxa_pwm_apply() argument
110 if (state->polarity != PWM_POLARITY_NORMAL) in pxa_pwm_apply()
111 return -EINVAL; in pxa_pwm_apply()
113 err = clk_prepare_enable(pc->clk); in pxa_pwm_apply()
117 duty_cycle = state->enabled ? state->duty_cycle : 0; in pxa_pwm_apply()
119 err = pxa_pwm_config(chip, pwm, duty_cycle, state->period); in pxa_pwm_apply()
121 clk_disable_unprepare(pc->clk); in pxa_pwm_apply()
125 if (state->enabled && !pwm->state.enabled) in pxa_pwm_apply()
128 clk_disable_unprepare(pc->clk); in pxa_pwm_apply()
130 if (!state->enabled && pwm->state.enabled) in pxa_pwm_apply()
131 clk_disable_unprepare(pc->clk); in pxa_pwm_apply()
143 * Device tree users must create one device instance for each PWM channel.
145 * code that this is a single channel pxa25x-pwm. Currently all devices are
149 { .compatible = "marvell,pxa250-pwm", .data = &pwm_id_table[0]},
150 { .compatible = "marvell,pxa270-pwm", .data = &pwm_id_table[0]},
151 { .compatible = "marvell,pxa168-pwm", .data = &pwm_id_table[0]},
152 { .compatible = "marvell,pxa910-pwm", .data = &pwm_id_table[0]},
167 id = of_device_get_match_data(&pdev->dev); in pwm_probe()
170 return -EINVAL; in pwm_probe()
172 pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); in pwm_probe()
174 return -ENOMEM; in pwm_probe()
176 pc->clk = devm_clk_get(&pdev->dev, NULL); in pwm_probe()
177 if (IS_ERR(pc->clk)) in pwm_probe()
178 return PTR_ERR(pc->clk); in pwm_probe()
180 pc->chip.dev = &pdev->dev; in pwm_probe()
181 pc->chip.ops = &pxa_pwm_ops; in pwm_probe()
182 pc->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1; in pwm_probe()
185 pc->chip.of_xlate = of_pwm_single_xlate; in pwm_probe()
186 pc->chip.of_pwm_n_cells = 1; in pwm_probe()
189 pc->mmio_base = devm_platform_ioremap_resource(pdev, 0); in pwm_probe()
190 if (IS_ERR(pc->mmio_base)) in pwm_probe()
191 return PTR_ERR(pc->mmio_base); in pwm_probe()
193 ret = devm_pwmchip_add(&pdev->dev, &pc->chip); in pwm_probe()
195 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); in pwm_probe()
204 .name = "pxa25x-pwm",