From 109b988f1aaddbfb8e1c0f4ae67a8fd9e9670703 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Fri, 27 Aug 2021 23:26:13 +0200 Subject: [PATCH 1/2] libsensors: Add support for pwm Add support for the pwm sensor interface. This includes support for pwm[1-*], pwm[1-*]_enable, pwm[1-*]_mode and pwm[1-*]_freq. --- CHANGES | 1 + doc/libsensors-API.txt | 3 +++ lib/sensors.h | 8 +++++++- lib/sysfs.c | 27 +++++++++++++++++++++++++-- 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 93cbd086..827ac1ea 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,7 @@ lm-sensors CHANGES file ----------------------- git HEAD + Add PWM sensor support 3.6.0 (2019-10-18) configs: Added a number of new configuration files diff --git a/doc/libsensors-API.txt b/doc/libsensors-API.txt index 70b8e6a6..7832d979 100644 --- a/doc/libsensors-API.txt +++ b/doc/libsensors-API.txt @@ -6,6 +6,9 @@ over time. This document summarizes these evolutions so that application authors can quickly figure out how to test for the availability of a given new feature. +0x501 +* Added support for pwm sensors + 0x500 lm-sensors 3.5.0 * Added support for power min, lcrit, min_alarm and lcrit_alarm enum sensors_subfeature_type SENSORS_SUBFEATURE_POWER_MIN diff --git a/lib/sensors.h b/lib/sensors.h index 94f6f230..644a4a9a 100644 --- a/lib/sensors.h +++ b/lib/sensors.h @@ -31,7 +31,7 @@ when the API or ABI breaks), the third digit is incremented to track small API additions like new flags / enum values. The second digit is for tracking larger additions like new methods. */ -#define SENSORS_API_VERSION 0x500 +#define SENSORS_API_VERSION 0x501 #define SENSORS_CHIP_NAME_PREFIX_ANY NULL #define SENSORS_CHIP_NAME_ADDR_ANY (-1) @@ -143,6 +143,7 @@ typedef enum sensors_feature_type { SENSORS_FEATURE_ENERGY = 0x04, SENSORS_FEATURE_CURR = 0x05, SENSORS_FEATURE_HUMIDITY = 0x06, + SENSORS_FEATURE_PWM = 0x07, SENSORS_FEATURE_MAX_MAIN, SENSORS_FEATURE_VID = 0x10, SENSORS_FEATURE_INTRUSION = 0x11, @@ -244,6 +245,11 @@ typedef enum sensors_subfeature_type { SENSORS_SUBFEATURE_HUMIDITY_INPUT = SENSORS_FEATURE_HUMIDITY << 8, + SENSORS_SUBFEATURE_PWM_IO = SENSORS_FEATURE_PWM << 8, + SENSORS_SUBFEATURE_PWM_FREQ, + SENSORS_SUBFEATURE_PWM_ENABLE = (SENSORS_FEATURE_PWM << 8) | 0x80, + SENSORS_SUBFEATURE_PWM_MODE, + SENSORS_SUBFEATURE_VID = SENSORS_FEATURE_VID << 8, SENSORS_SUBFEATURE_INTRUSION_ALARM = SENSORS_FEATURE_INTRUSION << 8, diff --git a/lib/sysfs.c b/lib/sysfs.c index 9516cec4..13624448 100644 --- a/lib/sysfs.c +++ b/lib/sysfs.c @@ -149,6 +149,7 @@ int get_type_scaling(sensors_subfeature_type type) case SENSORS_SUBFEATURE_HUMIDITY_INPUT: return 1000; case SENSORS_SUBFEATURE_FAN_INPUT: + case SENSORS_SUBFEATURE_PWM_IO: return 1; case SENSORS_SUBFEATURE_POWER_AVERAGE: case SENSORS_SUBFEATURE_ENERGY_INPUT: @@ -186,6 +187,13 @@ char *get_feature_name(sensors_feature_type ftype, char *sfname) if (!name) sensors_fatal_error(__func__, "Out of memory"); + break; + case SENSORS_FEATURE_PWM: + /* Not all pwm subfeatures have a underscore in there name */ + name = strndup(sfname, 4); + if (!name) + sensors_fatal_error(__func__, "Out of memory"); + break; default: name = strdup(sfname); @@ -319,6 +327,13 @@ static const struct subfeature_type_match humidity_matches[] = { { NULL, 0 } }; +static const struct subfeature_type_match pwm_matches[] = { + { "enable", SENSORS_SUBFEATURE_PWM_ENABLE }, + { "mode", SENSORS_SUBFEATURE_PWM_MODE }, + { "freq", SENSORS_SUBFEATURE_PWM_FREQ }, + { NULL, 0 } +}; + static const struct subfeature_type_match cpu_matches[] = { { "vid", SENSORS_SUBFEATURE_VID }, { NULL, 0 } @@ -339,6 +354,7 @@ static struct feature_type_match matches[] = { { "energy%d%c", energy_matches }, { "intrusion%d%c", intrusion_matches }, { "humidity%d%c", humidity_matches }, + { "pwm%d%c", pwm_matches }, }; /* Return the subfeature type and channel number based on the subfeature @@ -356,9 +372,15 @@ sensors_subfeature_type sensors_subfeature_get_type(const char *name, int *nr) return SENSORS_SUBFEATURE_BEEP_ENABLE; } - for (i = 0; i < ARRAY_SIZE(matches); i++) - if ((count = sscanf(name, matches[i].name, nr, &c))) + for (i = 0; i < ARRAY_SIZE(matches); i++) { + if ((count = sscanf(name, matches[i].name, nr, &c))) { + /* Needed for matching pwm[1-*] */ + if (count == 1 && matches[i].submatches == pwm_matches) + return SENSORS_SUBFEATURE_PWM_IO; + break; + } + } if (i == ARRAY_SIZE(matches) || count != 2 || c != '_') return SENSORS_SUBFEATURE_UNKNOWN; /* no match */ @@ -468,6 +490,7 @@ static int sensors_read_dynamic_chip(sensors_chip_features *chip, case SENSORS_FEATURE_ENERGY: case SENSORS_FEATURE_CURR: case SENSORS_FEATURE_HUMIDITY: + case SENSORS_FEATURE_PWM: nr--; break; default: From a6ec549ed68ba9ea2a13963cd713831c47701a5e Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Sat, 28 Aug 2021 01:04:13 +0200 Subject: [PATCH 2/2] sensors: Add support for pwm sensors Add print_chip_pwm for displaying SENSORS_FEATURE_PWM. --- prog/sensors/chips.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/prog/sensors/chips.c b/prog/sensors/chips.c index 0eb07418..c50f9a97 100644 --- a/prog/sensors/chips.c +++ b/prog/sensors/chips.c @@ -754,6 +754,59 @@ static void print_chip_humidity(const sensors_chip_name *name, free(label); } +static void print_chip_pwm(const sensors_chip_name *name, + const sensors_feature *feature, + int label_size) +{ + const sensors_subfeature *sfio, *sffreq, *sfenable, *sfmode; + char *label; + double val; + + if (!(label = sensors_get_label(name, feature))) { + fprintf(stderr, "ERROR: Can't get label of feature %s!\n", + feature->name); + return; + } + print_label(label, label_size); + free(label); + + sfio = sensors_get_subfeature(name, feature, + SENSORS_SUBFEATURE_PWM_IO); + if (sfio && !get_input_value(name, sfio, &val)) + printf(" %3.0f%%", val / 2.55); + else + printf(" N/A"); + + sffreq = sensors_get_subfeature(name, feature, + SENSORS_SUBFEATURE_PWM_FREQ); + sfmode = sensors_get_subfeature(name, feature, + SENSORS_SUBFEATURE_PWM_MODE); + if (sffreq || sfmode) { + printf(" ("); + if (sffreq) + printf("freq = %.0f Hz", get_value(name, sffreq)); + + if (sfmode) { + if (!get_input_value(name, sfmode, &val)) + printf("%smode = %s", sffreq ? ", " : "", + (int) val ? "pwm" : "dc"); + else + printf("%smode = N/A", sffreq ? ", " : ""); + } + + printf(")"); + } + + sfenable = sensors_get_subfeature(name, feature, + SENSORS_SUBFEATURE_PWM_ENABLE); + + if (sfenable && !get_input_value(name, sfenable, &val) && + (int) val == 1) + printf(" MANUAL CONTROL"); + + printf("\n"); +} + static void print_chip_beep_enable(const sensors_chip_name *name, const sensors_feature *feature, int label_size) @@ -894,6 +947,9 @@ void print_chip(const sensors_chip_name *name) case SENSORS_FEATURE_HUMIDITY: print_chip_humidity(name, feature, label_size); break; + case SENSORS_FEATURE_PWM: + print_chip_pwm(name, feature, label_size); + break; default: continue; }