123 lines
3.3 KiB
C
123 lines
3.3 KiB
C
#include <dirent.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "board-sensors.h"
|
|
|
|
int find_board_sensors(struct hwmon_avail_sensor *board_sensors, int max_sensors)
|
|
{
|
|
const char *hwmon_path = "/sys/class/hwmon/";
|
|
char device_path[NAME_MAX];
|
|
char sensor_path[NAME_MAX];
|
|
|
|
char driver_name[256];
|
|
|
|
FILE *file;
|
|
DIR *dir;
|
|
struct dirent *ent;
|
|
|
|
int num_sensors = 0;
|
|
|
|
/* Start looking for hwmon devices in /sys/class/hwmon/ */
|
|
dir = opendir(hwmon_path);
|
|
|
|
/* make sure we can open the device directory */
|
|
if(dir == NULL)
|
|
return 0;
|
|
|
|
/* loop over all hwmon devices */
|
|
while((ent = readdir(dir)) != NULL)
|
|
{
|
|
/* Ignore any non-hwmon dirs */
|
|
if(strncmp(ent->d_name, "hwmon", 5) != 0)
|
|
continue;
|
|
|
|
strcpy(device_path, hwmon_path);
|
|
strcat(device_path, ent->d_name);
|
|
|
|
/* Read in the name of the device */
|
|
strcpy(sensor_path, device_path);
|
|
strcat(sensor_path, "/name");
|
|
|
|
file = fopen(sensor_path, "r");
|
|
if (file == NULL)
|
|
continue;
|
|
|
|
if (fgets(driver_name, sizeof(driver_name), file) == NULL) {
|
|
fclose(file);
|
|
continue;
|
|
}
|
|
|
|
fclose(file);
|
|
|
|
/* Driver names have a linebreak at the end so let's remove that for comparison*/
|
|
driver_name[strlen(driver_name) - 1] = '\0';
|
|
|
|
/* Loop through all supported sensors and see if any are present in this device */
|
|
for (int i = 0; i < (sizeof(hwmon_sensor_info) / sizeof(struct hwmon_sensor)); i++) {
|
|
if (strcmp(driver_name, hwmon_sensor_info[i].driver_name) == 0) {
|
|
/* We matched the driver name, try to open the files */
|
|
strcpy(sensor_path, device_path);
|
|
strcat(sensor_path, "/");
|
|
strcat(sensor_path, hwmon_sensor_info[i].sensor_file_name);
|
|
strcat(sensor_path, "_input");
|
|
|
|
file = fopen(sensor_path, "r");
|
|
if (file != NULL) {
|
|
fclose(file);
|
|
/* Good open of the sensor file */
|
|
board_sensors[num_sensors].file = calloc(NAME_MAX, sizeof(char));
|
|
strcpy(board_sensors[num_sensors].file, sensor_path);
|
|
board_sensors[num_sensors].sort_index = i;
|
|
board_sensors[num_sensors].sensor_info = &hwmon_sensor_info[i];
|
|
|
|
/* Read in the sensor name */
|
|
board_sensors[num_sensors].sensor_name = calloc(MAX_SENSOR_NAME_LENGTH, sizeof(char));
|
|
strcpy(sensor_path, device_path);
|
|
strcat(sensor_path, "/");
|
|
strcat(sensor_path, hwmon_sensor_info[i].sensor_file_name);
|
|
strcat(sensor_path, "_label");
|
|
|
|
file = fopen(sensor_path, "r");
|
|
if (file != NULL)
|
|
fgets(board_sensors[num_sensors].sensor_name, MAX_SENSOR_NAME_LENGTH, file);
|
|
|
|
/* Sensor name seems to always have a trailing newline we don't want */
|
|
size_t len_without_newline = strcspn(board_sensors[num_sensors].sensor_name, "\n");
|
|
board_sensors[num_sensors].sensor_name[len_without_newline] = '\0';
|
|
|
|
if (num_sensors == max_sensors)
|
|
return num_sensors;
|
|
num_sensors++;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return num_sensors;
|
|
}
|
|
|
|
/* Returns 0 on a bad read or missing sensor, 1 on OK */
|
|
int get_sensor_reading(struct hwmon_avail_sensor *sensor, float *reading) {
|
|
char buf[256] = {0};
|
|
long int raw;
|
|
FILE *file;
|
|
|
|
file = fopen(sensor->file, "r");
|
|
if (file == NULL)
|
|
return 0;
|
|
|
|
fgets(buf, 256, file);
|
|
raw = strtol(buf, NULL, 10);
|
|
|
|
fclose(file);
|
|
|
|
*reading = (float)raw / sensor->sensor_info->divisor;
|
|
|
|
if (*reading == sensor->sensor_info->bad_value)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|