summaryrefslogtreecommitdiff
path: root/chip/lm4/pwm.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/lm4/pwm.c')
-rw-r--r--chip/lm4/pwm.c89
1 files changed, 20 insertions, 69 deletions
diff --git a/chip/lm4/pwm.c b/chip/lm4/pwm.c
index 6e52ebb369..943aa0210f 100644
--- a/chip/lm4/pwm.c
+++ b/chip/lm4/pwm.c
@@ -3,9 +3,13 @@
* found in the LICENSE file.
*/
-/* PWM control module for LM4 */
+/* PWM control module for LM4.
+ *
+ * On this chip, the PWM logic is implemented by the hardware FAN modules.
+ */
#include "clock.h"
+#include "fan_chip.h"
#include "gpio.h"
#include "hooks.h"
#include "pwm.h"
@@ -13,58 +17,39 @@
#include "registers.h"
#include "util.h"
-/* Maximum RPM for PWM controller */
-#define MAX_RPM 0x1fff
-
-/* Maximum PWM for PWM controller */
-#define MAX_PWM 0x1ff
-
-#define RPM_SCALE 2
-
void pwm_enable(enum pwm_channel ch, int enabled)
{
- const struct pwm_t *pwm = pwm_channels + ch;
- if (enabled)
- LM4_FAN_FANCTL |= (1 << pwm->channel);
- else
- LM4_FAN_FANCTL &= ~(1 << pwm->channel);
+ fan_chip_set_enabled(pwm_channels[ch].channel, enabled);
}
int pwm_get_enabled(enum pwm_channel ch)
{
- const struct pwm_t *pwm = pwm_channels + ch;
- return (LM4_FAN_FANCTL & (1 << pwm->channel)) ? 1 : 0;
+ return fan_chip_get_enabled(pwm_channels[ch].channel);
}
void pwm_set_duty(enum pwm_channel ch, int percent)
{
- const struct pwm_t *pwm = pwm_channels + ch;
- int duty;
-
if (percent < 0)
percent = 0;
else if (percent > 100)
percent = 100;
- if (pwm->flags & PWM_CONFIG_ACTIVE_LOW)
+ /* Assume the fan control is active high and invert it ourselves */
+ if (pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW)
percent = 100 - percent;
- duty = (MAX_PWM * percent + 50) / 100;
-
/* Always enable the channel */
pwm_enable(ch, 1);
/* Set the duty cycle */
- LM4_FAN_FANCMD(pwm->channel) = duty << 16;
+ fan_chip_set_duty(pwm_channels[ch].channel, percent);
}
int pwm_get_duty(enum pwm_channel ch)
{
- const struct pwm_t *pwm = pwm_channels + ch;
- int percent = ((LM4_FAN_FANCMD(pwm->channel) >> 16) * 100 + MAX_PWM / 2)
- / MAX_PWM;
+ int percent = fan_chip_get_duty(pwm_channels[ch].channel);
- if (pwm->flags & PWM_CONFIG_ACTIVE_LOW)
+ if (pwm_channels[ch].flags & PWM_CONFIG_ACTIVE_LOW)
percent = 100 - percent;
return percent;
@@ -73,47 +58,13 @@ int pwm_get_duty(enum pwm_channel ch)
static void pwm_init(void)
{
int i;
- const struct pwm_t *pwm;
-
- /* Enable the fan module and delay a few clocks */
- clock_enable_peripheral(CGC_OFFSET_FAN, 0x1,
- CGC_MODE_RUN | CGC_MODE_SLEEP);
-
- /* Disable all fans */
- LM4_FAN_FANCTL = 0;
- for (i = 0; i < PWM_CH_COUNT; ++i) {
- pwm = pwm_channels + i;
-
- if (pwm->flags & PWM_CONFIG_HAS_RPM_MODE) {
- /*
- * Configure PWM:
- * 0x8000 = bit 15 = auto-restart
- * 0x0000 = bit 14 = slow acceleration
- * 0x0000 = bits 13:11 = no hysteresis
- * 0x0000 = bits 10:8 = start period (2<<0) edges
- * 0x0000 = bits 7:6 = no fast start
- * 0x0020 = bits 5:4 = average 4 edges when
- * calculating RPM
- * 0x000c = bits 3:2 = 8 pulses per revolution
- * (see note at top of file)
- * 0x0000 = bit 0 = automatic control
- */
- LM4_FAN_FANCH(pwm->channel) = 0x802c;
- } else {
- /*
- * Configure keyboard backlight:
- * 0x0000 = bit 15 = no auto-restart
- * 0x0000 = bit 14 = slow acceleration
- * 0x0000 = bits 13:11 = no hysteresis
- * 0x0000 = bits 10:8 = start period (2<<0) edges
- * 0x0000 = bits 7:6 = no fast start
- * 0x0000 = bits 5:4 = no RPM averaging
- * 0x0000 = bits 3:2 = 1 pulses per revolution
- * 0x0001 = bit 0 = manual control
- */
- LM4_FAN_FANCH(pwm->channel) = 0x0001;
- }
- }
+ for (i = 0; i < PWM_CH_COUNT; ++i)
+ fan_chip_channel_setup(pwm_channels[i].channel,
+ (pwm_channels[i].flags &
+ PWM_CONFIG_HAS_RPM_MODE)
+ ? FAN_CHIP_USE_RPM_MODE : 0);
}
-DECLARE_HOOK(HOOK_INIT, pwm_init, HOOK_PRIO_INIT_PWM);
+
+/* The chip-specific fan module initializes before this. */
+DECLARE_HOOK(HOOK_INIT, pwm_init, HOOK_PRIO_DEFAULT);