Lines Matching full:pwm
9 * PWM driver for Samsung SoCs
21 #include <linux/pwm.h>
59 * struct samsung_pwm_channel - private data of PWM channel
71 * struct samsung_pwm_chip - private data of PWM chip
75 * @base: base address of mapped PWM registers
95 * PWM block is shared between pwm-samsung and samsung_pwm_timer drivers
101 * because all the supported SoCs contain only one instance of the PWM
121 struct pwm_device *pwm) in __pwm_samsung_manual_update() argument
123 unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm); in __pwm_samsung_manual_update()
200 "tclk of PWM %d is inoperational, using tdiv\n", chan); in pwm_samsung_calc_tin()
207 * Compare minimum PWM frequency that can be achieved with possible in pwm_samsung_calc_tin()
229 static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm) in pwm_samsung_request() argument
233 if (!(our_chip->variant.output_mask & BIT(pwm->hwpwm))) { in pwm_samsung_request()
235 "tried to request PWM channel %d without output\n", in pwm_samsung_request()
236 pwm->hwpwm); in pwm_samsung_request()
240 memset(&our_chip->channel[pwm->hwpwm], 0, sizeof(our_chip->channel[pwm->hwpwm])); in pwm_samsung_request()
245 static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm) in pwm_samsung_enable() argument
248 unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm); in pwm_samsung_enable()
264 our_chip->disabled_mask &= ~BIT(pwm->hwpwm); in pwm_samsung_enable()
271 static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm) in pwm_samsung_disable() argument
274 unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm); in pwm_samsung_disable()
285 * In case the PWM is at 100% duty cycle, force a manual in pwm_samsung_disable()
288 if (readl(our_chip->base + REG_TCMPB(pwm->hwpwm)) == (u32)-1U) in pwm_samsung_disable()
289 __pwm_samsung_manual_update(our_chip, pwm); in pwm_samsung_disable()
291 our_chip->disabled_mask |= BIT(pwm->hwpwm); in pwm_samsung_disable()
297 struct pwm_device *pwm) in pwm_samsung_manual_update() argument
303 __pwm_samsung_manual_update(our_chip, pwm); in pwm_samsung_manual_update()
308 static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm, in __pwm_samsung_config() argument
312 struct samsung_pwm_channel *chan = &our_chip->channel[pwm->hwpwm]; in __pwm_samsung_config()
315 tcnt = readl(our_chip->base + REG_TCNTB(pwm->hwpwm)); in __pwm_samsung_config()
316 oldtcmp = readl(our_chip->base + REG_TCMPB(pwm->hwpwm)); in __pwm_samsung_config()
321 /* Check to see if we are changing the clock rate of the PWM. */ in __pwm_samsung_config()
331 tin_rate = pwm_samsung_calc_tin(chip, pwm->hwpwm, period); in __pwm_samsung_config()
359 /* Update PWM registers. */ in __pwm_samsung_config()
360 writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm)); in __pwm_samsung_config()
361 writel(tcmp, our_chip->base + REG_TCMPB(pwm->hwpwm)); in __pwm_samsung_config()
364 * In case the PWM is currently at 100% duty cycle, force a manual in __pwm_samsung_config()
365 * update to prevent the signal staying high if the PWM is disabled in __pwm_samsung_config()
370 pwm_samsung_manual_update(our_chip, pwm); in __pwm_samsung_config()
380 static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm, in pwm_samsung_config() argument
383 return __pwm_samsung_config(chip, pwm, duty_ns, period_ns, false); in pwm_samsung_config()
411 struct pwm_device *pwm, in pwm_samsung_set_polarity() argument
418 pwm_samsung_set_invert(our_chip, pwm->hwpwm, invert); in pwm_samsung_set_polarity()
423 static int pwm_samsung_apply(struct pwm_chip *chip, struct pwm_device *pwm, in pwm_samsung_apply() argument
426 int err, enabled = pwm->state.enabled; in pwm_samsung_apply()
428 if (state->polarity != pwm->state.polarity) { in pwm_samsung_apply()
430 pwm_samsung_disable(chip, pwm); in pwm_samsung_apply()
434 err = pwm_samsung_set_polarity(chip, pwm, state->polarity); in pwm_samsung_apply()
441 pwm_samsung_disable(chip, pwm); in pwm_samsung_apply()
454 err = pwm_samsung_config(chip, pwm, state->duty_cycle, state->period); in pwm_samsung_apply()
458 if (!pwm->state.enabled) in pwm_samsung_apply()
459 err = pwm_samsung_enable(chip, pwm); in pwm_samsung_apply()
499 { .compatible = "samsung,s3c2410-pwm", .data = &s3c24xx_variant },
500 { .compatible = "samsung,s3c6400-pwm", .data = &s3c64xx_variant },
501 { .compatible = "samsung,s5p6440-pwm", .data = &s5p64x0_variant },
502 { .compatible = "samsung,s5pc100-pwm", .data = &s5pc100_variant },
503 { .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
521 of_property_for_each_u32(np, "samsung,pwm-outputs", val) { in pwm_samsung_parse_dt()
524 "%s: invalid channel index in samsung,pwm-outputs property\n", in pwm_samsung_parse_dt()
583 our_chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0"); in pwm_samsung_probe()
584 our_chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1"); in pwm_samsung_probe()
590 return dev_err_probe(dev, ret, "failed to register PWM chip\n"); in pwm_samsung_probe()
607 struct pwm_device *pwm = &chip->pwms[i]; in pwm_samsung_resume() local
610 if (!test_bit(PWMF_REQUESTED, &pwm->flags)) in pwm_samsung_resume()
618 __pwm_samsung_config(chip, pwm, chan->duty_ns, in pwm_samsung_resume()
620 /* needed to make PWM disable work on Odroid-XU3 */ in pwm_samsung_resume()
621 pwm_samsung_manual_update(our_chip, pwm); in pwm_samsung_resume()
625 pwm_samsung_disable(chip, pwm); in pwm_samsung_resume()
627 pwm_samsung_enable(chip, pwm); in pwm_samsung_resume()
637 .name = "samsung-pwm",
648 MODULE_ALIAS("platform:samsung-pwm");