From e98b6befcafdbc838b75a1a79500dc1ed77452ff Mon Sep 17 00:00:00 2001 From: Vic Yang Date: Tue, 20 Dec 2011 18:50:37 +0800 Subject: [PATCH] Add EC host command to control fan speed. Add LPC host command to get and set fan speed. BUG=chrome-os-partner:7313 TEST=Connect a fan and manually test fan actual speed matches target speed. Change-Id: I4b6a711a1b8cca0dbd1c1936fe4f0f15240d3453 --- common/build.mk | 3 ++- common/host_command.c | 13 +++++++++--- common/main.c | 1 + common/pwm_commands.c | 32 ++++++++++++++++++++++++++++ include/lpc_commands.h | 15 +++++++++++++ include/pwm_commands.h | 19 +++++++++++++++++ util/ectool.c | 48 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 common/pwm_commands.c create mode 100644 include/pwm_commands.h diff --git a/common/build.mk b/common/build.mk index 1943d688c3..3eb42ec2fd 100644 --- a/common/build.mk +++ b/common/build.mk @@ -4,4 +4,5 @@ common-objs=main.o util.o console.o vboot.o common-objs+=flash_commands.o host_command.o port80.o keyboard.o i8042.o -common-objs+=memory_commands.o shared_mem.o temp_sensor_commands.o +common-objs+=memory_commands.o shared_mem.o temp_sensor_commands.o pwm_commands.o +common-objs+=memory_commands.o shared_mem.o pwm_commands.o diff --git a/common/host_command.c b/common/host_command.c index 0d7c959792..aa72535987 100644 --- a/common/host_command.c +++ b/common/host_command.c @@ -10,6 +10,7 @@ #include "flash_commands.h" #include "host_command.h" #include "temp_sensor_commands.h" +#include "pwm_commands.h" #include "lpc.h" #include "lpc_commands.h" #include "system.h" @@ -176,6 +177,12 @@ static void command_process(int slot) case EC_LPC_COMMAND_TEMP_SENSOR_GET_READINGS: lpc_send_host_response(slot, temp_sensor_command_get_readings(data)); return; + case EC_LPC_COMMAND_PWM_GET_FAN_RPM: + lpc_send_host_response(slot, pwm_command_get_fan_rpm(data)); + return; + case EC_LPC_COMMAND_PWM_SET_FAN_TARGET_RPM: + lpc_send_host_response(slot, pwm_command_set_fan_target_rpm(data)); + return; default: lpc_send_host_response(slot, EC_LPC_STATUS_INVALID_COMMAND); } @@ -198,11 +205,11 @@ static int command_version(int argc, char **argv) static const struct console_command console_commands[] = { - {"version", command_version}, + {"version", command_version}, }; static const struct console_group command_group = { - "Host commands", console_commands, ARRAY_SIZE(console_commands) + "Host commands", console_commands, ARRAY_SIZE(console_commands) }; /*****************************************************************************/ @@ -212,7 +219,7 @@ static int host_command_init(void) { host_command[0] = host_command[1] = -1; - console_register_commands(&command_group); + console_register_commands(&command_group); return EC_SUCCESS; } diff --git a/common/main.c b/common/main.c index c9e1bbe75d..5ea2607b14 100644 --- a/common/main.c +++ b/common/main.c @@ -23,6 +23,7 @@ #include "port80.h" #include "powerdemo.h" #include "pwm.h" +#include "pwm_commands.h" #include "system.h" #include "task.h" #include "temp_sensor.h" diff --git a/common/pwm_commands.c b/common/pwm_commands.c new file mode 100644 index 0000000000..7581fe56ba --- /dev/null +++ b/common/pwm_commands.c @@ -0,0 +1,32 @@ +/* Copyright (c) 2011 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 module for Chrome EC */ + +#include "pwm.h" +#include "pwm_commands.h" +#include "lpc_commands.h" + + +/*****************************************************************************/ +/* Host commands */ + +enum lpc_status pwm_command_get_fan_rpm(uint8_t *data) +{ + struct lpc_response_pwm_get_fan_rpm *r = + (struct lpc_response_pwm_get_fan_rpm *)data; + + r->rpm = pwm_get_fan_rpm(); + return EC_LPC_STATUS_SUCCESS; +} + +enum lpc_status pwm_command_set_fan_target_rpm(uint8_t *data) +{ + struct lpc_params_pwm_set_fan_target_rpm *p = + (struct lpc_params_pwm_set_fan_target_rpm *)data; + + pwm_set_fan_target_rpm(p->rpm); + return EC_LPC_STATUS_SUCCESS; +} diff --git a/include/lpc_commands.h b/include/lpc_commands.h index a7ba4818c9..151256cde5 100644 --- a/include/lpc_commands.h +++ b/include/lpc_commands.h @@ -204,6 +204,21 @@ struct lpc_response_flash_checksum { } while (0) #endif /* SUPPORT_CHECKSUM */ +/*****************************************************************************/ +/* PWM commands */ + +/* Get fan RPM */ +#define EC_LPC_COMMAND_PWM_GET_FAN_RPM 0x20 +struct lpc_response_pwm_get_fan_rpm { + uint32_t rpm; +} __attribute__ ((packed)); + +/* Set target fan RPM */ +#define EC_LPC_COMMAND_PWM_SET_FAN_TARGET_RPM 0x21 +struct lpc_params_pwm_set_fan_target_rpm { + uint32_t rpm; +} __attribute__ ((packed)); + /*****************************************************************************/ /* Temperature sensor commands */ diff --git a/include/pwm_commands.h b/include/pwm_commands.h new file mode 100644 index 0000000000..31f397c6fe --- /dev/null +++ b/include/pwm_commands.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2011 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 commands for Chrome EC */ + +#ifndef __CROS_EC_PWM_COMMANDS_H +#define __CROS_EC_PWM_COMMANDS_H + +#include "common.h" +#include "lpc_commands.h" + +/* Host command handlers. */ +enum lpc_status pwm_command_get_fan_rpm(uint8_t *data); +enum lpc_status pwm_command_set_fan_target_rpm(uint8_t *data); + + +#endif /* __CROS_EC_PWM_COMMANDS_H */ diff --git a/util/ectool.c b/util/ectool.c index 11012069d9..1446c5b065 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -37,6 +37,10 @@ const char help_str[] = " Prints EC version\n" " temps\n" " Print temperature\n" + " pwmgetfanrpm\n" + " Prints current fan RPM\n" + " pwmsetfanrpm \n" + " Set target fan RPM\n" "\n" "Not working for you? Make sure LPC I/O is configured:\n" " pci_write32 0 0x1f 0 0x88 0x007c0801\n" @@ -460,6 +464,46 @@ int cmd_temperature(void) return 0; } +int cmd_pwm_get_fan_rpm(void) +{ + struct lpc_response_pwm_get_fan_rpm r; + int rv; + + rv = ec_command(EC_LPC_COMMAND_PWM_GET_FAN_RPM, NULL, 0, &r, sizeof(r)); + if (rv) + return rv; + + printf("Current fan RPM: %d\n", r.rpm); + + return 0; +} + +int cmd_pwm_set_fan_rpm(int argc, char *argv[]) +{ + struct lpc_params_pwm_set_fan_target_rpm p; + char *e; + int rv; + + if (argc != 1) { + fprintf(stderr, + "Usage: pwmsetfanrpm \n"); + return -1; + } + p.rpm = strtol(argv[0], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad RPM.\n"); + return -1; + } + + rv = ec_command(EC_LPC_COMMAND_PWM_SET_FAN_TARGET_RPM, + &p, sizeof(p), NULL, 0); + if (rv) + return rv; + + printf("Fan target RPM set.\n"); + return 0; +} + int main(int argc, char *argv[]) { if (argc < 2 || !strcasecmp(argv[1], "-?") || @@ -493,6 +537,10 @@ int main(int argc, char *argv[]) return cmd_version(); if (!strcasecmp(argv[1], "temps")) return cmd_temperature(); + if (!strcasecmp(argv[1], "pwmgetfanrpm")) + return cmd_pwm_get_fan_rpm(); + if (!strcasecmp(argv[1], "pwmsetfanrpm")) + return cmd_pwm_set_fan_rpm(argc - 2, argv + 2); /* If we're still here, command was unknown */ fprintf(stderr, "Unknown command '%s'\n\n", argv[1]);