Added compact sensor display option
This commit is contained in:
parent
9f29076d52
commit
113e296347
@ -84,6 +84,7 @@ struct card_info {
|
|||||||
char *card_name;
|
char *card_name;
|
||||||
char *pci_id;
|
char *pci_id;
|
||||||
char *i2c_dev_path;
|
char *i2c_dev_path;
|
||||||
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gpu_pci_info {
|
struct gpu_pci_info {
|
||||||
|
30
evga-icx.c
30
evga-icx.c
@ -19,15 +19,17 @@ static const char helpstring[] = "Available options:\n"
|
|||||||
" N to set the fan to that manual % speed\n"
|
" N to set the fan to that manual % speed\n"
|
||||||
" [+/-]N to set that fan to an RPM offset from the GPU-controlled speed\n"
|
" [+/-]N to set that fan to an RPM offset from the GPU-controlled speed\n"
|
||||||
"--reset : Reset all fans to their default mode\n"
|
"--reset : Reset all fans to their default mode\n"
|
||||||
"--sensors : Print sensor readings even if setting a fan speed \n";
|
"--sensors : Print sensor readings even if setting a fan speed \n"
|
||||||
|
"--compact : Print sensor reading in a compact one-line per card format\n";
|
||||||
|
|
||||||
void print_gpu_info(int gpu_num, struct card_info gpus[]);
|
void print_gpu_info(int gpu_num, struct card_info gpus[], int compact);
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct card_info gpus[MAX_GPUS];
|
struct card_info gpus[MAX_GPUS];
|
||||||
int gpu_count;
|
int gpu_count;
|
||||||
int print_info = 0;
|
int print_info = 0;
|
||||||
|
int compact = 0;
|
||||||
int gpu_num = -1; /* Card to control */
|
int gpu_num = -1; /* Card to control */
|
||||||
char *fan_speed[ICX3_MAX_FANS] = {NULL};
|
char *fan_speed[ICX3_MAX_FANS] = {NULL};
|
||||||
|
|
||||||
@ -65,6 +67,8 @@ int main (int argc, char **argv)
|
|||||||
fan_speed[j] = "auto";
|
fan_speed[j] = "auto";
|
||||||
} else if (strcmp(argv[i], "--sensors") == 0) {
|
} else if (strcmp(argv[i], "--sensors") == 0) {
|
||||||
print_info = 1;
|
print_info = 1;
|
||||||
|
} else if (strcmp(argv[i], "--compact") == 0) {
|
||||||
|
compact = 1;
|
||||||
} else {
|
} else {
|
||||||
printf(helpstring);
|
printf(helpstring);
|
||||||
return 0;
|
return 0;
|
||||||
@ -117,19 +121,27 @@ int main (int argc, char **argv)
|
|||||||
if (print_info) {
|
if (print_info) {
|
||||||
if (gpu_num == -1) {
|
if (gpu_num == -1) {
|
||||||
for (int i = 0; i < gpu_count; i++){
|
for (int i = 0; i < gpu_count; i++){
|
||||||
print_gpu_info(i, gpus);
|
print_gpu_info(i, gpus, compact);
|
||||||
}
|
}
|
||||||
} else if (gpu_num <= gpu_count - 1) {
|
} else if (gpu_num <= gpu_count - 1) {
|
||||||
print_gpu_info(gpu_num, gpus);
|
print_gpu_info(gpu_num, gpus, compact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_gpu_info(int gpu_num, struct card_info gpus[]) {
|
void print_gpu_info(int gpu_num, struct card_info gpus[], int compact) {
|
||||||
printf("#%d: %s (%s) @ %s\n", gpu_num, gpus[gpu_num].card_name, gpus[gpu_num].i2c_dev_path, gpus[gpu_num].pci_id);
|
if (compact) {
|
||||||
print_icx3_fans(gpus[gpu_num].i2c_dev_path);
|
printf("#%d ", gpu_num);
|
||||||
print_icx3_temps(gpus[gpu_num].i2c_dev_path);
|
print_icx3_fans_oneline(gpus[gpu_num].i2c_dev_path);
|
||||||
printf("\n");
|
print_icx3_temps_oneline(gpus[gpu_num].i2c_dev_path);
|
||||||
|
printf("\n");
|
||||||
|
} else {
|
||||||
|
printf("#%d: %s (%s) @ %s\n", gpu_num, gpus[gpu_num].card_name, gpus[gpu_num].i2c_dev_path, gpus[gpu_num].pci_id);
|
||||||
|
print_icx3_fans(gpus[gpu_num].i2c_dev_path);
|
||||||
|
print_icx3_temps(gpus[gpu_num].i2c_dev_path);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
139
icx3.c
139
icx3.c
@ -33,72 +33,59 @@ enum icx3_product_id check_for_icx3(char *i2c_dev_path)
|
|||||||
|
|
||||||
void print_icx3_fans(char *i2c_dev_path)
|
void print_icx3_fans(char *i2c_dev_path)
|
||||||
{
|
{
|
||||||
char data[I2C_SMBUS_BLOCK_MAX] = {};
|
struct icx3_fan_control fans[ICX3_MAX_FANS];
|
||||||
int fd, read_result;
|
get_fan_status(fans, i2c_dev_path);
|
||||||
|
|
||||||
struct icx3_fan_control *fan_status;
|
for (int i=0; i < ICX3_MAX_FANS; i++) {
|
||||||
|
|
||||||
/* First thing is to check for the product ID to figure out how many fans we have */
|
|
||||||
char fans_avail[ICX3_MAX_FANS] = {0};
|
|
||||||
get_available_fans(i2c_dev_path, fans_avail);
|
|
||||||
|
|
||||||
fd = open_i2c_dev(i2c_dev_path);
|
|
||||||
if (fd == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int i=0; i < ICX3_MAX_FANS; i++) {
|
|
||||||
if (!fans_avail[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
read_result = i2c_smbus_read_i2c_block_data(fd, ICX3_REG_FANCONTROL + i, ICX3_FANCONTROL_SIZE, data);
|
|
||||||
if (read_result != ICX3_FANCONTROL_SIZE) {
|
|
||||||
close(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fan_status = (struct icx3_fan_control*) &data;
|
|
||||||
printf("%s: %d RPM (%d/%d%%, %s)\n",
|
printf("%s: %d RPM (%d/%d%%, %s)\n",
|
||||||
icx3_fan_names[i],
|
icx3_fan_names[i],
|
||||||
fan_status->rpm_status,
|
fans[i].rpm_status,
|
||||||
fan_status->duty_status,
|
fans[i].duty_status,
|
||||||
fan_status->duty,
|
fans[i].duty,
|
||||||
icx3_fan_mode_names[fan_status->fanmode]
|
icx3_fan_mode_names[fans[i].fanmode]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_icx3_fans_oneline(char *i2c_dev_path)
|
||||||
|
{
|
||||||
|
struct icx3_fan_control fans[ICX3_MAX_FANS];
|
||||||
|
get_fan_status(fans, i2c_dev_path);
|
||||||
|
|
||||||
close(fd);
|
printf("FAN");
|
||||||
|
for (int i=0; i < ICX3_MAX_FANS; i++) {
|
||||||
|
printf(" %3d", fans[i].duty_status);
|
||||||
|
}
|
||||||
|
printf("%%");
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_icx3_temps(char *i2c_dev_path)
|
void print_icx3_temps(char *i2c_dev_path)
|
||||||
{
|
{
|
||||||
char data[I2C_SMBUS_BLOCK_MAX] = {};
|
float temps[ICX3_NUM_TEMP_SENSORS];
|
||||||
int fd, read_result;
|
|
||||||
struct icx3_temp_sensors *temp_sensors;
|
|
||||||
|
|
||||||
fd = open_i2c_dev(i2c_dev_path);
|
get_temp_sensors(temps, i2c_dev_path);
|
||||||
if (fd == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
read_result = i2c_smbus_read_i2c_block_data(fd, ICX3_REG_TEMPSENSOR, ICX3_TEMPSENSOR_SIZE, data);
|
|
||||||
if (read_result != ICX3_TEMPSENSOR_SIZE) {
|
|
||||||
close(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
temp_sensors = (struct icx3_temp_sensors*) &data;
|
|
||||||
|
|
||||||
float cur_temp;
|
|
||||||
short cur_data;
|
|
||||||
|
|
||||||
for (int i=0; i<ICX3_NUM_TEMP_SENSORS; i++) {
|
for (int i=0; i<ICX3_NUM_TEMP_SENSORS; i++) {
|
||||||
/* endian swap */
|
|
||||||
cur_data = (short)(temp_sensors->data[2*i+1] << 8) | (short)(temp_sensors->data[2*i]);
|
|
||||||
/* temp is reported in tenths of deg C */
|
|
||||||
cur_temp = (float)cur_data/10;
|
|
||||||
printf("%s: %+.1f°C\n",
|
printf("%s: %+.1f°C\n",
|
||||||
icx3_temp_sensor_names[i],
|
icx3_temp_sensor_names[i],
|
||||||
cur_temp);
|
temps[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_icx3_temps_oneline(char *i2c_dev_path)
|
||||||
|
{
|
||||||
|
float temps[ICX3_NUM_TEMP_SENSORS];
|
||||||
|
|
||||||
|
get_temp_sensors(temps, i2c_dev_path);
|
||||||
|
|
||||||
|
for (int i=0; i<ICX3_NUM_TEMP_SENSORS; i++) {
|
||||||
|
if (i == 0 || strncmp(icx3_temp_sensor_names[i], icx3_temp_sensor_names[i-1], 3))
|
||||||
|
printf(" %.3s", icx3_temp_sensor_names[i]);
|
||||||
|
printf(" %3.0f", temps[i]);
|
||||||
|
}
|
||||||
|
printf("°C");
|
||||||
|
}
|
||||||
|
|
||||||
void get_available_fans(char *i2c_dev_path, char *fans_avail)
|
void get_available_fans(char *i2c_dev_path, char *fans_avail)
|
||||||
{
|
{
|
||||||
int product_id = check_for_icx3(i2c_dev_path);
|
int product_id = check_for_icx3(i2c_dev_path);
|
||||||
@ -155,6 +142,62 @@ void get_available_fans(char *i2c_dev_path, char *fans_avail)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_fan_status(struct icx3_fan_control *fans, char *i2c_dev_path)
|
||||||
|
{
|
||||||
|
char data[I2C_SMBUS_BLOCK_MAX] = {};
|
||||||
|
int fd, read_result;
|
||||||
|
|
||||||
|
/* First thing is to check for the product ID to figure out how many fans we have */
|
||||||
|
char fans_avail[ICX3_MAX_FANS] = {0};
|
||||||
|
get_available_fans(i2c_dev_path, fans_avail);
|
||||||
|
|
||||||
|
fd = open_i2c_dev(i2c_dev_path);
|
||||||
|
if (fd == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i=0; i < ICX3_MAX_FANS; i++) {
|
||||||
|
if (!fans_avail[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_result = i2c_smbus_read_i2c_block_data(fd, ICX3_REG_FANCONTROL + i, ICX3_FANCONTROL_SIZE, data);
|
||||||
|
if (read_result != ICX3_FANCONTROL_SIZE) {
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(&fans[i], &data, sizeof(struct icx3_fan_control));
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_temp_sensors(float *temps, char *i2c_dev_path)
|
||||||
|
{
|
||||||
|
char data[I2C_SMBUS_BLOCK_MAX] = {};
|
||||||
|
int fd, read_result;
|
||||||
|
struct icx3_temp_sensors *temp_sensors;
|
||||||
|
|
||||||
|
fd = open_i2c_dev(i2c_dev_path);
|
||||||
|
if (fd == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
read_result = i2c_smbus_read_i2c_block_data(fd, ICX3_REG_TEMPSENSOR, ICX3_TEMPSENSOR_SIZE, data);
|
||||||
|
close(fd);
|
||||||
|
if (read_result != ICX3_TEMPSENSOR_SIZE)
|
||||||
|
return;
|
||||||
|
temp_sensors = (struct icx3_temp_sensors*) &data;
|
||||||
|
|
||||||
|
float cur_temp;
|
||||||
|
short cur_data;
|
||||||
|
|
||||||
|
for (int i=0; i<ICX3_NUM_TEMP_SENSORS; i++) {
|
||||||
|
/* endian swap */
|
||||||
|
cur_data = (short)(temp_sensors->data[2*i+1] << 8) | (short)(temp_sensors->data[2*i]);
|
||||||
|
/* temp is reported in tenths of deg C */
|
||||||
|
temps[i] = (float)cur_data/10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int open_i2c_dev(char *i2c_dev_path)
|
int open_i2c_dev(char *i2c_dev_path)
|
||||||
{
|
{
|
||||||
int fd = open(i2c_dev_path, O_RDONLY);
|
int fd = open(i2c_dev_path, O_RDONLY);
|
||||||
|
6
icx3.h
6
icx3.h
@ -113,8 +113,12 @@ static char *icx3_temp_sensor_names[] = {
|
|||||||
|
|
||||||
enum icx3_product_id check_for_icx3(char *i2c_dev_path);
|
enum icx3_product_id check_for_icx3(char *i2c_dev_path);
|
||||||
void print_icx3_fans(char *i2c_dev_path);
|
void print_icx3_fans(char *i2c_dev_path);
|
||||||
|
void print_icx3_fans_oneline(char *i2c_dev_path);
|
||||||
void print_icx3_temps(char *i2c_dev_path);
|
void print_icx3_temps(char *i2c_dev_path);
|
||||||
|
void print_icx3_temps_oneline(char *i2c_dev_path);
|
||||||
void get_available_fans(char *i2c_dev_path, char *fans_avail);
|
void get_available_fans(char *i2c_dev_path, char *fans_avail);
|
||||||
|
void get_fan_status(struct icx3_fan_control *fans, char *i2c_dev_path);
|
||||||
|
void get_temp_sensors(float *temps, char *i2c_dev_path);
|
||||||
int open_i2c_dev(char *i2c_dev_path);
|
int open_i2c_dev(char *i2c_dev_path);
|
||||||
void enable_write(int enable, char *i2c_dev_path);
|
void enable_write(int enable, char *i2c_dev_path);
|
||||||
void set_fan(int fan, char *setting, char *i2c_dev_path);
|
void set_fan(int fan, char *setting, char *i2c_dev_path);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user