Lines Matching +full:pwm +full:- +full:period

1 // SPDX-License-Identifier: GPL-2.0-only
12 #include <linux/pwm.h>
29 #define IPROC_PWM_PRESCALE_SHIFT(ch) ((3 - (ch)) * \
50 value = readl(ip->base + IPROC_PWM_CTRL_OFFSET); in iproc_pwmc_enable()
52 writel(value, ip->base + IPROC_PWM_CTRL_OFFSET); in iproc_pwmc_enable()
62 value = readl(ip->base + IPROC_PWM_CTRL_OFFSET); in iproc_pwmc_disable()
64 writel(value, ip->base + IPROC_PWM_CTRL_OFFSET); in iproc_pwmc_disable()
70 static int iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm, in iproc_pwmc_get_state() argument
77 value = readl(ip->base + IPROC_PWM_CTRL_OFFSET); in iproc_pwmc_get_state()
79 if (value & BIT(IPROC_PWM_CTRL_EN_SHIFT(pwm->hwpwm))) in iproc_pwmc_get_state()
80 state->enabled = true; in iproc_pwmc_get_state()
82 state->enabled = false; in iproc_pwmc_get_state()
84 if (value & BIT(IPROC_PWM_CTRL_POLARITY_SHIFT(pwm->hwpwm))) in iproc_pwmc_get_state()
85 state->polarity = PWM_POLARITY_NORMAL; in iproc_pwmc_get_state()
87 state->polarity = PWM_POLARITY_INVERSED; in iproc_pwmc_get_state()
89 rate = clk_get_rate(ip->clk); in iproc_pwmc_get_state()
91 state->period = 0; in iproc_pwmc_get_state()
92 state->duty_cycle = 0; in iproc_pwmc_get_state()
96 value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET); in iproc_pwmc_get_state()
97 prescale = value >> IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm); in iproc_pwmc_get_state()
102 value = readl(ip->base + IPROC_PWM_PERIOD_OFFSET(pwm->hwpwm)); in iproc_pwmc_get_state()
104 state->period = div64_u64(tmp, rate); in iproc_pwmc_get_state()
106 value = readl(ip->base + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm)); in iproc_pwmc_get_state()
108 state->duty_cycle = div64_u64(tmp, rate); in iproc_pwmc_get_state()
113 static int iproc_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm, in iproc_pwmc_apply() argument
118 u32 value, period, duty; in iproc_pwmc_apply() local
121 rate = clk_get_rate(ip->clk); in iproc_pwmc_apply()
124 * Find period count, duty count and prescale to suit duty_cycle and in iproc_pwmc_apply()
125 * period. This is done according to formulas described below: in iproc_pwmc_apply()
137 value = rate * state->period; in iproc_pwmc_apply()
138 period = div64_u64(value, div); in iproc_pwmc_apply()
139 value = rate * state->duty_cycle; in iproc_pwmc_apply()
142 if (period < IPROC_PWM_PERIOD_MIN) in iproc_pwmc_apply()
143 return -EINVAL; in iproc_pwmc_apply()
145 if (period <= IPROC_PWM_PERIOD_MAX && in iproc_pwmc_apply()
151 return -EINVAL; in iproc_pwmc_apply()
154 iproc_pwmc_disable(ip, pwm->hwpwm); in iproc_pwmc_apply()
157 value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET); in iproc_pwmc_apply()
158 value &= ~IPROC_PWM_PRESCALE_MASK(pwm->hwpwm); in iproc_pwmc_apply()
159 value |= prescale << IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm); in iproc_pwmc_apply()
160 writel(value, ip->base + IPROC_PWM_PRESCALE_OFFSET); in iproc_pwmc_apply()
162 /* set period and duty cycle */ in iproc_pwmc_apply()
163 writel(period, ip->base + IPROC_PWM_PERIOD_OFFSET(pwm->hwpwm)); in iproc_pwmc_apply()
164 writel(duty, ip->base + IPROC_PWM_DUTY_CYCLE_OFFSET(pwm->hwpwm)); in iproc_pwmc_apply()
167 value = readl(ip->base + IPROC_PWM_CTRL_OFFSET); in iproc_pwmc_apply()
169 if (state->polarity == PWM_POLARITY_NORMAL) in iproc_pwmc_apply()
170 value |= 1 << IPROC_PWM_CTRL_POLARITY_SHIFT(pwm->hwpwm); in iproc_pwmc_apply()
172 value &= ~(1 << IPROC_PWM_CTRL_POLARITY_SHIFT(pwm->hwpwm)); in iproc_pwmc_apply()
174 writel(value, ip->base + IPROC_PWM_CTRL_OFFSET); in iproc_pwmc_apply()
176 if (state->enabled) in iproc_pwmc_apply()
177 iproc_pwmc_enable(ip, pwm->hwpwm); in iproc_pwmc_apply()
195 chip = devm_pwmchip_alloc(&pdev->dev, 4, sizeof(*ip)); in iproc_pwmc_probe()
202 chip->ops = &iproc_pwm_ops; in iproc_pwmc_probe()
204 ip->base = devm_platform_ioremap_resource(pdev, 0); in iproc_pwmc_probe()
205 if (IS_ERR(ip->base)) in iproc_pwmc_probe()
206 return PTR_ERR(ip->base); in iproc_pwmc_probe()
208 ip->clk = devm_clk_get_enabled(&pdev->dev, NULL); in iproc_pwmc_probe()
209 if (IS_ERR(ip->clk)) in iproc_pwmc_probe()
210 return dev_err_probe(&pdev->dev, PTR_ERR(ip->clk), in iproc_pwmc_probe()
214 value = readl(ip->base + IPROC_PWM_CTRL_OFFSET); in iproc_pwmc_probe()
216 for (i = 0; i < chip->npwm; i++) { in iproc_pwmc_probe()
221 writel(value, ip->base + IPROC_PWM_CTRL_OFFSET); in iproc_pwmc_probe()
223 ret = devm_pwmchip_add(&pdev->dev, chip); in iproc_pwmc_probe()
225 return dev_err_probe(&pdev->dev, ret, in iproc_pwmc_probe()
226 "failed to add PWM chip\n"); in iproc_pwmc_probe()
232 { .compatible = "brcm,iproc-pwm" },
239 .name = "bcm-iproc-pwm",
247 MODULE_DESCRIPTION("Broadcom iProc PWM driver");