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
72 * @chip: generic PWM chip
76 * @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()
134 static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm, in pwm_samsung_set_divisor() argument
142 bits = (fls(divisor) - 1) - pwm->variant.div_base; in pwm_samsung_set_divisor()
146 reg = readl(pwm->base + REG_TCFG1); in pwm_samsung_set_divisor()
149 writel(reg, pwm->base + REG_TCFG1); in pwm_samsung_set_divisor()
199 "tclk of PWM %d is inoperational, using tdiv\n", chan); in pwm_samsung_calc_tin()
206 * Compare minimum PWM frequency that can be achieved with possible in pwm_samsung_calc_tin()
228 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()
244 pwm_set_chip_data(pwm, our_chan); in pwm_samsung_request()
249 static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm) in pwm_samsung_free() argument
251 kfree(pwm_get_chip_data(pwm)); in pwm_samsung_free()
254 static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm) in pwm_samsung_enable() argument
257 unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm); in pwm_samsung_enable()
273 our_chip->disabled_mask &= ~BIT(pwm->hwpwm); in pwm_samsung_enable()
280 static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm) in pwm_samsung_disable() argument
283 unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm); in pwm_samsung_disable()
294 * In case the PWM is at 100% duty cycle, force a manual in pwm_samsung_disable()
297 if (readl(our_chip->base + REG_TCMPB(pwm->hwpwm)) == (u32)-1U) in pwm_samsung_disable()
298 __pwm_samsung_manual_update(our_chip, pwm); in pwm_samsung_disable()
300 our_chip->disabled_mask |= BIT(pwm->hwpwm); in pwm_samsung_disable()
306 struct pwm_device *pwm) in pwm_samsung_manual_update() argument
312 __pwm_samsung_manual_update(chip, pwm); in pwm_samsung_manual_update()
317 static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm, in __pwm_samsung_config() argument
321 struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm); in __pwm_samsung_config()
324 tcnt = readl(our_chip->base + REG_TCNTB(pwm->hwpwm)); in __pwm_samsung_config()
325 oldtcmp = readl(our_chip->base + REG_TCMPB(pwm->hwpwm)); in __pwm_samsung_config()
330 /* Check to see if we are changing the clock rate of the PWM. */ in __pwm_samsung_config()
340 tin_rate = pwm_samsung_calc_tin(our_chip, pwm->hwpwm, period); in __pwm_samsung_config()
369 /* Update PWM registers. */ in __pwm_samsung_config()
370 writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm)); in __pwm_samsung_config()
371 writel(tcmp, our_chip->base + REG_TCMPB(pwm->hwpwm)); in __pwm_samsung_config()
374 * In case the PWM is currently at 100% duty cycle, force a manual in __pwm_samsung_config()
375 * update to prevent the signal staying high if the PWM is disabled in __pwm_samsung_config()
380 pwm_samsung_manual_update(our_chip, pwm); in __pwm_samsung_config()
390 static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm, in pwm_samsung_config() argument
393 return __pwm_samsung_config(chip, pwm, duty_ns, period_ns, false); in pwm_samsung_config()
421 struct pwm_device *pwm, in pwm_samsung_set_polarity() argument
428 pwm_samsung_set_invert(our_chip, pwm->hwpwm, invert); in pwm_samsung_set_polarity()
433 static int pwm_samsung_apply(struct pwm_chip *chip, struct pwm_device *pwm, in pwm_samsung_apply() argument
436 int err, enabled = pwm->state.enabled; in pwm_samsung_apply()
438 if (state->polarity != pwm->state.polarity) { in pwm_samsung_apply()
440 pwm_samsung_disable(chip, pwm); in pwm_samsung_apply()
444 err = pwm_samsung_set_polarity(chip, pwm, state->polarity); in pwm_samsung_apply()
451 pwm_samsung_disable(chip, pwm); in pwm_samsung_apply()
464 err = pwm_samsung_config(chip, pwm, state->duty_cycle, state->period); in pwm_samsung_apply()
468 if (!pwm->state.enabled) in pwm_samsung_apply()
469 err = pwm_samsung_enable(chip, pwm); in pwm_samsung_apply()
511 { .compatible = "samsung,s3c2410-pwm", .data = &s3c24xx_variant },
512 { .compatible = "samsung,s3c6400-pwm", .data = &s3c64xx_variant },
513 { .compatible = "samsung,s5p6440-pwm", .data = &s5p64x0_variant },
514 { .compatible = "samsung,s5pc100-pwm", .data = &s5pc100_variant },
515 { .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
534 of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) { in pwm_samsung_parse_dt()
537 "%s: invalid channel index in samsung,pwm-outputs property\n", in pwm_samsung_parse_dt()
604 chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0"); in pwm_samsung_probe()
605 chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1"); in pwm_samsung_probe()
611 dev_err(dev, "failed to register PWM chip\n"); in pwm_samsung_probe()
643 struct pwm_device *pwm = &chip->pwms[i]; in pwm_samsung_resume() local
644 struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm); in pwm_samsung_resume()
654 __pwm_samsung_config(chip, pwm, chan->duty_ns, in pwm_samsung_resume()
656 /* needed to make PWM disable work on Odroid-XU3 */ in pwm_samsung_resume()
657 pwm_samsung_manual_update(our_chip, pwm); in pwm_samsung_resume()
661 pwm_samsung_disable(chip, pwm); in pwm_samsung_resume()
663 pwm_samsung_enable(chip, pwm); in pwm_samsung_resume()
674 .name = "samsung-pwm",
685 MODULE_ALIAS("platform:samsung-pwm");