static int pwm_imx27_apply()

in pwm-imx27.c [215:292]


static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			   const struct pwm_state *state)
{
	unsigned long period_cycles, duty_cycles, prescale;
	struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
	struct pwm_state cstate;
	unsigned long long c;
	unsigned long long clkrate;
	int ret;
	u32 cr;

	pwm_get_state(pwm, &cstate);

	clkrate = clk_get_rate(imx->clk_per);
	c = clkrate * state->period;

	do_div(c, NSEC_PER_SEC);
	period_cycles = c;

	prescale = period_cycles / 0x10000 + 1;

	period_cycles /= prescale;
	c = clkrate * state->duty_cycle;
	do_div(c, NSEC_PER_SEC);
	duty_cycles = c;
	duty_cycles /= prescale;

	/*
	 * according to imx pwm RM, the real period value should be PERIOD
	 * value in PWMPR plus 2.
	 */
	if (period_cycles > 2)
		period_cycles -= 2;
	else
		period_cycles = 0;

	/*
	 * Wait for a free FIFO slot if the PWM is already enabled, and flush
	 * the FIFO if the PWM was disabled and is about to be enabled.
	 */
	if (cstate.enabled) {
		pwm_imx27_wait_fifo_slot(chip, pwm);
	} else {
		ret = pwm_imx27_clk_prepare_enable(imx);
		if (ret)
			return ret;

		pwm_imx27_sw_reset(chip);
	}

	writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
	writel(period_cycles, imx->mmio_base + MX3_PWMPR);

	/*
	 * Store the duty cycle for future reference in cases where the
	 * MX3_PWMSAR register can't be read (i.e. when the PWM is disabled).
	 */
	imx->duty_cycle = duty_cycles;

	cr = MX3_PWMCR_PRESCALER_SET(prescale) |
	     MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN |
	     FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH) |
	     MX3_PWMCR_DBGEN;

	if (state->polarity == PWM_POLARITY_INVERSED)
		cr |= FIELD_PREP(MX3_PWMCR_POUTC,
				MX3_PWMCR_POUTC_INVERTED);

	if (state->enabled)
		cr |= MX3_PWMCR_EN;

	writel(cr, imx->mmio_base + MX3_PWMCR);

	if (!state->enabled)
		pwm_imx27_clk_disable_unprepare(imx);

	return 0;
}