hwmon: (cgbc-hwmon) Fix current sensors ID lookup

Current sensors on the Congatec Board Controller don't use consecutive IDs,
unlike other sensor types (voltage, temperature, fan). The driver assumed
consecutive IDs and performed a simple lookup, which caused an unknown
sensor warning. Define current sensor IDs explicitly.

Changes the warning on conga-SA7 (type and channel are correct now).
Before:
  Board Controller returned an unknown sensor (type=2, channel=17), ignore it
After:
  Board Controller returned an unknown sensor (bc_type=1, bc_id=11), ignore it

Cc: stable@kernel.org
Fixes: 08ebc9def7 ("hwmon: Add Congatec Board Controller monitoring driver")
Signed-off-by: Thomas Richard (congatec GmbH) <thomas.richard@bootlin.com>
Link: https://patch.msgid.link/20260911-cgbc-hwmon-fix-and-new-sensors-v2-1-0c6bf078d173@bootlin.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
Thomas Richard (congatec GmbH) 2026-09-11 19:31:58 +02:00 committed by Guenter Roeck
parent 26d5ff7976
commit 7bae83ffb1

View File

@ -52,30 +52,35 @@ static const char * const cgbc_hwmon_labels_temp[] = {
"BOTTOMDIM Temperature",
};
static const struct {
enum hwmon_sensor_types type;
const char *label;
} cgbc_hwmon_labels_in[] = {
{ hwmon_in, "CPU Voltage" },
{ hwmon_in, "DC Runtime Voltage" },
{ hwmon_in, "DC Standby Voltage" },
{ hwmon_in, "CMOS Battery Voltage" },
{ hwmon_in, "Battery Voltage" },
{ hwmon_in, "AC Voltage" },
{ hwmon_in, "Other Voltage" },
{ hwmon_in, "5V Voltage" },
{ hwmon_in, "5V Standby Voltage" },
{ hwmon_in, "3V3 Voltage" },
{ hwmon_in, "3V3 Standby Voltage" },
{ hwmon_in, "VCore A Voltage" },
{ hwmon_in, "VCore B Voltage" },
{ hwmon_in, "12V Voltage" },
{ hwmon_curr, "DC Current" },
{ hwmon_curr, "5V Current" },
{ hwmon_curr, "12V Current" },
static const char * const cgbc_hwmon_labels_in[] = {
"CPU Voltage",
"DC Runtime Voltage",
"DC Standby Voltage",
"CMOS Battery Voltage",
"Battery Voltage",
"AC Voltage",
"Other Voltage",
"5V Voltage",
"5V Standby Voltage",
"3V3 Voltage",
"3V3 Standby Voltage",
"VCore A Voltage",
"VCore B Voltage",
"12V Voltage",
};
#define CGBC_HWMON_NB_IN_SENSORS 14
/*
* Current sensors are a bit special, they don't have consecutive IDs like
* other types of sensors. So they need to be defined explicitly.
*/
static const struct {
const char *label;
int id;
} cgbc_hwmon_labels_curr[] = {
{ "DC Current", 0x12 },
{ "5V Current", 0x18 },
{ "12V Current", 0x1E },
};
static const char * const cgbc_hwmon_labels_fan[] = {
"CPU Fan",
@ -114,7 +119,8 @@ static int cgbc_hwmon_probe_sensors(struct device *dev, struct cgbc_hwmon_data *
for (i = 0; i < nb_sensors; i++) {
enum cgbc_sensor_types type;
unsigned int channel;
unsigned int channel, id;
int j;
/*
* No need to request data for the first sensor.
@ -128,32 +134,49 @@ static int cgbc_hwmon_probe_sensors(struct device *dev, struct cgbc_hwmon_data *
}
type = FIELD_GET(CGBC_HWMON_TYPE_MASK, data[1]);
channel = FIELD_GET(CGBC_HWMON_ID_MASK, data[1]) - 1;
id = FIELD_GET(CGBC_HWMON_ID_MASK, data[1]);
channel = id - 1;
if (type == CGBC_HWMON_TYPE_TEMP && channel < ARRAY_SIZE(cgbc_hwmon_labels_temp)) {
sensor->type = hwmon_temp;
sensor->label = cgbc_hwmon_labels_temp[channel];
} else if (type == CGBC_HWMON_TYPE_IN &&
channel < ARRAY_SIZE(cgbc_hwmon_labels_in)) {
} else if (type == CGBC_HWMON_TYPE_IN) {
/*
* The Board Controller doesn't differentiate current and voltage sensors.
* Get the sensor type from cgbc_hwmon_labels_in[channel].type instead.
* First check if it is a current sensor.
*/
sensor->type = cgbc_hwmon_labels_in[channel].type;
sensor->label = cgbc_hwmon_labels_in[channel].label;
for (j = 0; j < ARRAY_SIZE(cgbc_hwmon_labels_curr); j++) {
if (id == cgbc_hwmon_labels_curr[j].id) {
sensor->type = hwmon_curr;
sensor->label = cgbc_hwmon_labels_curr[j].label;
channel = j;
}
}
/* If it's not a current sensor, it may be a voltage sensor. */
if (!sensor->label && channel < ARRAY_SIZE(cgbc_hwmon_labels_in)) {
sensor->type = hwmon_in;
sensor->label = cgbc_hwmon_labels_in[channel];
}
} else if (type == CGBC_HWMON_TYPE_FAN &&
channel < ARRAY_SIZE(cgbc_hwmon_labels_fan)) {
sensor->type = hwmon_fan;
sensor->label = cgbc_hwmon_labels_fan[channel];
} else {
dev_warn(dev, "Board Controller returned an unknown sensor (type=%d, channel=%d), ignore it",
type, channel);
}
if (!sensor->label) {
dev_warn(dev, "Board Controller returned an unknown sensor (bc_type=%d, bc_id=%d), ignore it",
type, id);
continue;
}
sensor->active = FIELD_GET(CGBC_HWMON_ACTIVE_BIT, data[1]);
sensor->channel = channel;
sensor->index = i;
dev_dbg(dev, "Found sensor: bc_type=%d, bc_id=%d, hwmon_type=%d, hwmon_channel=%d, hwmon_label='%s', active=%d\n",
type, id, sensor->type, sensor->channel, sensor->label, sensor->active);
sensor++;
hwmon->nb_sensors++;
}
@ -167,14 +190,6 @@ static struct cgbc_hwmon_sensor *cgbc_hwmon_find_sensor(struct cgbc_hwmon_data *
struct cgbc_hwmon_sensor *sensor = NULL;
int i;
/*
* The Board Controller doesn't differentiate current and voltage sensors.
* The channel value (from the Board Controller point of view) shall be computed for current
* sensors.
*/
if (type == hwmon_curr)
channel += CGBC_HWMON_NB_IN_SENSORS;
for (i = 0; i < hwmon->nb_sensors; i++) {
if (hwmon->sensors[i].type == type && hwmon->sensors[i].channel == channel) {
sensor = &hwmon->sensors[i];