diff options
Diffstat (limited to 'chip/it83xx/pwm.c')
-rw-r--r-- | chip/it83xx/pwm.c | 281 |
1 files changed, 0 insertions, 281 deletions
diff --git a/chip/it83xx/pwm.c b/chip/it83xx/pwm.c deleted file mode 100644 index fda8dd23d6..0000000000 --- a/chip/it83xx/pwm.c +++ /dev/null @@ -1,281 +0,0 @@ -/* Copyright 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* PWM control module for IT83xx. */ - -#include "clock.h" -#include "gpio.h" -#include "hooks.h" -#include "pwm.h" -#include "pwm_chip.h" -#include "registers.h" -#include "util.h" -#include "math_util.h" - -#define PWM_CTRX_MIN 100 -#define PWM_EC_FREQ 8000000 - -const struct pwm_ctrl_t pwm_ctrl_regs[] = { - { &IT83XX_PWM_DCR0, &IT83XX_PWM_PCSSGL, &IT83XX_GPIO_GPCRA0}, - { &IT83XX_PWM_DCR1, &IT83XX_PWM_PCSSGL, &IT83XX_GPIO_GPCRA1}, - { &IT83XX_PWM_DCR2, &IT83XX_PWM_PCSSGL, &IT83XX_GPIO_GPCRA2}, - { &IT83XX_PWM_DCR3, &IT83XX_PWM_PCSSGL, &IT83XX_GPIO_GPCRA3}, - { &IT83XX_PWM_DCR4, &IT83XX_PWM_PCSSGH, &IT83XX_GPIO_GPCRA4}, - { &IT83XX_PWM_DCR5, &IT83XX_PWM_PCSSGH, &IT83XX_GPIO_GPCRA5}, - { &IT83XX_PWM_DCR6, &IT83XX_PWM_PCSSGH, &IT83XX_GPIO_GPCRA6}, - { &IT83XX_PWM_DCR7, &IT83XX_PWM_PCSSGH, &IT83XX_GPIO_GPCRA7}, -}; - -const struct pwm_ctrl_t2 pwm_clock_ctrl_regs[] = { - { &IT83XX_PWM_CTR, &IT83XX_PWM_C0CPRS, &IT83XX_PWM_C0CPRS, - &IT83XX_PWM_PCFSR, 0x01}, - { &IT83XX_PWM_CTR1, &IT83XX_PWM_C4CPRS, &IT83XX_PWM_C4MCPRS, - &IT83XX_PWM_PCFSR, 0x02}, - { &IT83XX_PWM_CTR2, &IT83XX_PWM_C6CPRS, &IT83XX_PWM_C6MCPRS, - &IT83XX_PWM_PCFSR, 0x04}, - { &IT83XX_PWM_CTR3, &IT83XX_PWM_C7CPRS, &IT83XX_PWM_C7MCPRS, - &IT83XX_PWM_PCFSR, 0x08}, -}; - -static int pwm_get_cycle_time(enum pwm_channel ch) -{ - int pcs_shift; - int pcs_mask; - int pcs_reg; - int cycle_time_setting; - - /* pwm channel mapping */ - ch = pwm_channels[ch].channel; - - /* bit shift for "Prescaler Clock Source Select Group" register. */ - pcs_shift = (ch % 4) * 2; - - /* setting of "Prescaler Clock Source Select Group" register. */ - pcs_reg = *pwm_ctrl_regs[ch].pwm_clock_source; - - /* only bit0 bit1 information. */ - pcs_mask = (pcs_reg >> pcs_shift) & 0x03; - - /* get cycle time setting of PWM channel x. */ - cycle_time_setting = *pwm_clock_ctrl_regs[pcs_mask].pwm_cycle_time; - - return cycle_time_setting; -} - -void pwm_enable(enum pwm_channel ch, int enabled) -{ - /* pwm channel mapping */ - int pwm_reg_index = pwm_channels[ch].channel; - - /* - * enabled : pin to PWM function. - * disabled : pin to GPIO input function. - */ - if (enabled) - *pwm_ctrl_regs[pwm_reg_index].pwm_pin = 0x00; - else - *pwm_ctrl_regs[pwm_reg_index].pwm_pin = 0x80 | - ((pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW) ? - 4 : 2); -} - -int pwm_get_enabled(enum pwm_channel ch) -{ - /* pwm channel mapping */ - ch = pwm_channels[ch].channel; - - /* pin is PWM function and PWMs clock counter was enabled */ - return ((*pwm_ctrl_regs[ch].pwm_pin & ~0x04) == 0x00 && - IT83XX_PWM_ZTIER & 0x02) ? 1 : 0; -} - -void pwm_set_duty(enum pwm_channel ch, int percent) -{ - int pcs_shift; - int pcs_mask; - int pcs_reg; - int cycle_time_setting; - - if (percent < 0) - percent = 0; - else if (percent > 100) - percent = 100; - - if (pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW) - percent = 100 - percent; - - /* pwm channel mapping */ - ch = pwm_channels[ch].channel; - - /* bit shift for "Prescaler Clock Source Select Group" register. */ - pcs_shift = (ch % 4) * 2; - - /* setting of "Prescaler Clock Source Select Group" register.*/ - pcs_reg = *pwm_ctrl_regs[ch].pwm_clock_source; - - /* only bit0 bit1 information. */ - pcs_mask = (pcs_reg >> pcs_shift) & 0x03; - - /* get cycle time setting of PWM channel x. */ - cycle_time_setting = *pwm_clock_ctrl_regs[pcs_mask].pwm_cycle_time; - - /* to update PWM DCRx depend on CTRx setting. */ - if (percent == 100) { - *pwm_ctrl_regs[ch].pwm_duty = cycle_time_setting; - } else { - *pwm_ctrl_regs[ch].pwm_duty = - ((cycle_time_setting + 1) * percent) / 100; - } -} - -int pwm_get_duty(enum pwm_channel ch) -{ - int pcs_mask; - int pcs_reg; - int cycle_time_setting; - int percent; - int ch_idx; - - ch_idx = ch; - - /* pwm channel mapping */ - ch = pwm_channels[ch].channel; - - /* setting of "Prescaler Clock Source Select Group" register.*/ - pcs_reg = *pwm_ctrl_regs[ch].pwm_clock_source; - - /* only bit0 bit1 information. */ - pcs_mask = (pcs_reg >> ((ch % 4) * 2)) & 0x03; - - /* get cycle time setting of PWM channel x. */ - cycle_time_setting = *pwm_clock_ctrl_regs[pcs_mask].pwm_cycle_time; - - percent = *pwm_ctrl_regs[ch].pwm_duty * 100 / cycle_time_setting; - - if (pwm_channels[ch_idx].flags & PWM_CONFIG_ACTIVE_LOW) - percent = 100 - percent; - - /* output signal duty cycle. */ - return percent; -} - -void pwm_duty_inc(enum pwm_channel ch) -{ - int cycle_time, pwm_ch; - - /* pwm channel mapping */ - pwm_ch = pwm_channels[ch].channel; - - cycle_time = pwm_get_cycle_time(ch); - - if (pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW) { - if (*pwm_ctrl_regs[pwm_ch].pwm_duty > 0) - *pwm_ctrl_regs[pwm_ch].pwm_duty -= 1; - } else { - if (*pwm_ctrl_regs[pwm_ch].pwm_duty < cycle_time) - *pwm_ctrl_regs[pwm_ch].pwm_duty += 1; - } -} - -void pwm_duty_reduce(enum pwm_channel ch) -{ - int cycle_time, pwm_ch; - - /* pwm channel mapping */ - pwm_ch = pwm_channels[ch].channel; - - cycle_time = pwm_get_cycle_time(ch); - - if (pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW) { - if (*pwm_ctrl_regs[pwm_ch].pwm_duty < cycle_time) - *pwm_ctrl_regs[pwm_ch].pwm_duty += 1; - } else { - if (*pwm_ctrl_regs[pwm_ch].pwm_duty > 0) - *pwm_ctrl_regs[pwm_ch].pwm_duty -= 1; - } -} - -static int pwm_ch_freq(enum pwm_channel ch) -{ - int actual_freq = -1, targe_freq, deviation; - int pcfsr, ctr, pcfsr_sel, pcs_shift, pcs_mask; - int pwm_clk_src = (pwm_channels[ch].flags & PWM_CONFIG_DSLEEP) ? - 32768 : PWM_EC_FREQ; - - targe_freq = pwm_channels[ch].freq_hz; - deviation = (targe_freq / 100) + 1; - - for (ctr = 0xFF; ctr >= PWM_CTRX_MIN; ctr--) { - pcfsr = (pwm_clk_src / (ctr + 1) / targe_freq) - 1; - if (pcfsr >= 0) { - actual_freq = pwm_clk_src / (ctr + 1) / (pcfsr + 1); - if (ABS(actual_freq - targe_freq) < deviation) - break; - } - } - - if (ctr < PWM_CTRX_MIN) { - actual_freq = -1; - } else { - pcfsr_sel = pwm_channels[ch].pcfsr_sel; - *pwm_clock_ctrl_regs[pcfsr_sel].pwm_cycle_time = ctr; - - if (pwm_channels[ch].flags & PWM_CONFIG_DSLEEP) - /* - * Select 32.768KHz as PWM clock source. -] * - * NOTE: - * For pwm_channels[], the maximum supported pwm output - * signal frequency is 324 Hz (32768/(PWM_CTRX_MIN+1)). - */ - *pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_reg &= - ~pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_ctrl; - else - /* ec clock 8MHz */ - *pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_reg |= - pwm_clock_ctrl_regs[pcfsr_sel].pwm_pcfsr_ctrl; - - /* pwm channel mapping */ - ch = pwm_channels[ch].channel; - - /* - * bit shift for "Prescaler Clock Source Select Group" - * register. - */ - pcs_shift = (ch % 4) * 2; - pcs_mask = pcfsr_sel << pcs_shift; - - *pwm_ctrl_regs[ch].pwm_clock_source &= ~(0x3 << pcs_shift); - *pwm_ctrl_regs[ch].pwm_clock_source |= pcs_mask; - - *pwm_clock_ctrl_regs[pcfsr_sel].pwm_cpr_lsb = pcfsr & 0xFF; - *pwm_clock_ctrl_regs[pcfsr_sel].pwm_cpr_msb = - (pcfsr >> 8) & 0xFF; - } - - return actual_freq; -} - -static void pwm_init(void) -{ - int ch; - - for (ch = 0; ch < PWM_CH_COUNT; ch++) - pwm_ch_freq(ch); - - /* - * The cycle timer1 of chip 8320 later series was enhanced from - * 8bits to 10bits resolution, and others are still 8bit resolution. - * Because the cycle timer1 high byte default value is not zero, - * we clear cycle timer1 high byte at init and use it as 8-bit - * resolution like others. - */ - IT83XX_PWM_CTR1M = 0; - /* enable PWMs clock counter. */ - IT83XX_PWM_ZTIER |= 0x02; -} - -/* The chip PWM module initialization. */ -DECLARE_HOOK(HOOK_INIT, pwm_init, HOOK_PRIO_INIT_PWM); |