Example #1
0
/**
 * Get PWM duty cycle.
 *
 * @param   ch  operation channel
 * @return  duty cycle percent
 */
int pwm_get_duty(enum pwm_channel ch)
{
	int mdl = pwm_channels[ch].channel;
	/* Return percent */
	if ((!pwm_get_enabled(ch)) || (NPCX_DCR(mdl) > NPCX_CTR(mdl)))
		return 0;
	else
		return ((NPCX_DCR(mdl) + 1) * 100) / (NPCX_CTR(mdl) + 1);
}
Example #2
0
File: pwm.c Project: thehobn/ec
/**
 * PWM configuration.
 *
 * @param ch                        operation channel
 * @return none
 */
void pwm_config(enum pwm_channel ch)
{
	pwm_init_ch = ch;

	/* Configure pins from GPIOs to PWM */
	if (ch == PWM_CH_FAN)
		gpio_config_module(MODULE_PWM_FAN, 1);
	else
		gpio_config_module(MODULE_PWM_KBLIGHT, 1);

	/* Disable PWM for module configuration */
	pwm_enable(ch, 0);

	/* Set PWM heartbeat mode is no heartbeat*/
	NPCX_PWMCTL(pwm_channels[ch].channel) =
			(NPCX_PWMCTL(pwm_channels[ch].channel)
			&(~(((1<<2)-1)<<NPCX_PWMCTL_HB_DC_CTL)))
			|(NPCX_PWM_HBM_NORMAL<<NPCX_PWMCTL_HB_DC_CTL);

	/* Set PWM operation frequence */
	pwm_freq_changed();

	/* Set PWM cycle time */
	NPCX_CTR(pwm_channels[ch].channel) =
			(pwm_channels[ch].cycle_pulses - 1);

	/* Set the duty cycle */
	NPCX_DCR(pwm_channels[ch].channel) = 0;

	/* Set PWM polarity is normal*/
	CLEAR_BIT(NPCX_PWMCTL(pwm_channels[ch].channel), NPCX_PWMCTL_INVP);

	/* Set PWM open drain output is push-pull type*/
	CLEAR_BIT(NPCX_PWMCTL(pwm_channels[ch].channel), NPCX_PWMCTLEX_OD_OUT);

	/* Select default CLK or LFCLK clock input to PWM module */
	NPCX_PWMCTLEX(pwm_channels[ch].channel) =
			(NPCX_PWMCTLEX(pwm_channels[ch].channel)
			& (~(((1<<2)-1)<<NPCX_PWMCTLEX_FCK_SEL)))
			| (NPCX_PWM_CLOCK_APB2_LFCLK<<NPCX_PWMCTLEX_FCK_SEL);

	if (ch == PWM_CH_FAN) {
#ifdef CONFIG_PWM_INPUT_LFCLK
		/* Select default LFCLK clock input to PWM module */
		SET_BIT(NPCX_PWMCTL(pwm_channels[ch].channel),
				NPCX_PWMCTL_CKSEL);
#else
		/* Select default core clock input to PWM module */
		CLEAR_BIT(NPCX_PWMCTL(pwm_channels[ch].channel),
				NPCX_PWMCTL_CKSEL);
#endif
	} else {
		/* Select default core clock input to PWM module */
		CLEAR_BIT(NPCX_PWMCTL(pwm_channels[ch].channel),
				NPCX_PWMCTL_CKSEL);
	}
}
Example #3
0
File: pwm.c Project: thehobn/ec
/**
 * Get PWM duty cycle.
 *
 * @param   ch  operation channel
 * @return  duty cycle percent
 */
int pwm_get_duty(enum pwm_channel ch)
{
	/* Return percent */
	if (0 == pwm_get_enabled(ch))
		return 0;
	else
		return (((NPCX_DCR(pwm_channels[ch].channel) + 1) * 100)
				/ (NPCX_CTR(pwm_channels[ch].channel) + 1));
}
Example #4
0
/**
 * Set PWM duty cycle.
 *
 * @param   ch      operation channel
 * @param   percent duty cycle percent
 * @return  none
 */
void pwm_set_duty(enum pwm_channel ch, int percent)
{
	int mdl = pwm_channels[ch].channel;
	uint32_t dc_res = 0;
	uint16_t dc_cnt = 0;

	/* Checking duty value first */
	if (percent < 0)
		percent = 0;
	else if (percent > 100)
		percent = 100;
	CPRINTS("pwm%d, set duty=%d", mdl, percent);

	/* Assume the fan control is active high and invert it ourselves */
	UPDATE_BIT(NPCX_PWMCTL(mdl), NPCX_PWMCTL_INVP,
			(pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW));

	dc_res = NPCX_CTR(mdl) + 1;
	dc_cnt = (percent*dc_res)/100;
	CPRINTS("freq=0x%x", pwm_channels[ch].freq);
	CPRINTS("duty_cycle_res=%d", dc_res);
	CPRINTS("duty_cycle_cnt=%d", dc_cnt);


	/* Set the duty cycle */
	if (percent > 0) {
		if (percent == 100)
			NPCX_DCR(mdl) = NPCX_CTR(mdl);
		else
			NPCX_DCR(mdl) = (dc_cnt - 1);
		pwm_enable(ch, 1);
	} else {
		/* Output low since DCR > CTR */
		NPCX_DCR(mdl) = NPCX_CTR(mdl) + 1;
		pwm_enable(ch, 0);
	}
}
Example #5
0
File: pwm.c Project: thehobn/ec
/**
 * Set PWM duty cycle.
 *
 * @param   ch      operation channel
 * @param   percent duty cycle percent
 * @return  none
 */
void pwm_set_duty(enum pwm_channel ch, int percent)
{
	uint32_t resolution = 0;
	uint16_t duty_cycle = 0;

	CPRINTS("pwm0=%d", percent);
	/* Assume the fan control is active high and invert it ourselves */
	if (pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW)
		SET_BIT(NPCX_PWMCTL(pwm_channels[ch].channel),
				NPCX_PWMCTL_INVP);
	else
		CLEAR_BIT(NPCX_PWMCTL(pwm_channels[ch].channel),
				NPCX_PWMCTL_INVP);

	if (percent < 0)
		percent = 0;
	/* (Benson_TBD_14) if 100% make mft cannot get TCRB,
	 * it will need to change to 99% */
	else if (percent > 100)
		percent = 100;
	CPRINTS("pwm1duty=%d", percent);

	resolution = NPCX_CTR(pwm_channels[ch].channel) + 1;
	duty_cycle = percent*resolution/100;
	CPRINTS("freq=0x%x", pwm_channels[ch].freq);
	CPRINTS("resolution=%d", resolution);
	CPRINTS("duty_cycle=%d", duty_cycle);

	/* Set the duty cycle */
	/* (Benson_TBD_14) Always enable the fan channel or not */
	if (percent) {
		NPCX_DCR(pwm_channels[ch].channel) = (duty_cycle - 1);
		pwm_enable(ch, 1);
	} else {
		NPCX_DCR(pwm_channels[ch].channel) = 0;
		pwm_enable(ch, 0);
	}
}
Example #6
0
/**
 * Set PWM operation clock.
 *
 * @param   ch      operation channel
 * @param   freq    desired PWM frequency
 * @param   res     resolution for duty cycle
 * @notes   changed when initialization
 */
void pwm_set_freq(enum pwm_channel ch, uint32_t freq, uint32_t res)
{
	int mdl = pwm_channels[ch].channel;
	uint32_t prescaler_divider = 0;
	uint32_t clock;

	/* Disable PWM for module configuration */
	pwm_enable(ch, 0);

	/* Get PWM clock frequency */
	if (pwm_channels[ch].flags & PWM_CONFIG_DSLEEP_CLK)
		clock = INT_32K_CLOCK;
	else
		clock = clock_get_apb2_freq();

	/*
	 * Using PWM Frequency and Resolution we calculate
	 * prescaler for input clock
	 */
	prescaler_divider = ((clock / freq)/res);

	/* Set clock prescaler divider to PWM module*/
	if (prescaler_divider >= 1)
		prescaler_divider = prescaler_divider - 1;
	if (prescaler_divider > 0xFFFF)
		prescaler_divider = 0xFFFF;

	/* Configure computed prescaler and resolution */
	NPCX_PRSC(mdl) = (uint16_t)prescaler_divider - 1;

	/* Set PWM cycle time */
	NPCX_CTR(mdl) = res - 1;

	/* Set the duty cycle to 0% since DCR > CTR */
	NPCX_DCR(mdl) = res;
}