struct waterforce_data { struct hid_device *hdev; struct device *hwmon_dev; struct dentry *debugfs; /* For locking access to buffer */ struct mutex buffer_lock; /* For queueing multiple readers */ struct mutex status_report_request_mutex; /* For reinitializing the completion below */
spinlock_t status_report_request_lock; struct completion status_report_received; struct completion fw_version_processed;
/* Sensor data */
s32 temp_input[1];
u16 speed_input[2]; /* Fan and pump speed in RPM */
u8 duty_input[2]; /* Fan and pump duty in 0-100% */
u8 *buffer; int firmware_version; unsignedlong updated; /* jiffies */
};
static umode_t waterforce_is_visible(constvoid *data, enum hwmon_sensor_types type, u32 attr, int channel)
{ switch (type) { case hwmon_temp: switch (attr) { case hwmon_temp_label: case hwmon_temp_input: return0444; default: break;
} break; case hwmon_fan: switch (attr) { case hwmon_fan_label: case hwmon_fan_input: return0444; default: break;
} break; case hwmon_pwm: switch (attr) { case hwmon_pwm_input: return0444; default: break;
} break; default: break;
}
return0;
}
/* Writes the command to the device with the rest of the report filled with zeroes */ staticint waterforce_write_expanded(struct waterforce_data *priv, const u8 *cmd, int cmd_length)
{ int ret;
mutex_lock(&priv->buffer_lock);
memcpy_and_pad(priv->buffer, MAX_REPORT_LENGTH, cmd, cmd_length, 0x00);
ret = hid_hw_output_report(priv->hdev, priv->buffer, MAX_REPORT_LENGTH);
mutex_unlock(&priv->buffer_lock); return ret;
}
staticint waterforce_get_status(struct waterforce_data *priv)
{ int ret = mutex_lock_interruptible(&priv->status_report_request_mutex);
if (ret < 0) return ret;
if (!time_after(jiffies, priv->updated + msecs_to_jiffies(STATUS_VALIDITY))) { /* Data is up to date */ goto unlock_and_return;
}
/* Send command for getting status */
ret = waterforce_write_expanded(priv, get_status_cmd, GET_STATUS_CMD_LENGTH); if (ret < 0) goto unlock_and_return;
ret = wait_for_completion_interruptible_timeout(&priv->status_report_received,
msecs_to_jiffies(STATUS_VALIDITY)); if (ret == 0)
ret = -ETIMEDOUT;
unlock_and_return:
mutex_unlock(&priv->status_report_request_mutex); if (ret < 0) return ret;
return0;
}
staticint waterforce_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
{ struct waterforce_data *priv = dev_get_drvdata(dev); int ret = waterforce_get_status(priv);
spin_lock(&priv->status_report_request_lock); if (!completion_done(&priv->status_report_received))
complete_all(&priv->status_report_received);
spin_unlock(&priv->status_report_request_lock);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.