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: return 0444; default: break;
} break; case hwmon_fan: switch (attr) { case hwmon_fan_label: case hwmon_fan_input: return 0444; default: break;
} break; case hwmon_pwm: switch (attr) { case hwmon_pwm_input: return 0444; default: break;
} break; default: break;
}
return 0;
}
/* 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;
}
/* * Disable raw event parsing for a moment to safely reinitialize the * completion. Reinit is done because hidraw could have triggered * the raw event parsing and marked the priv->status_report_received * completion as done.
*/
spin_lock_bh(&priv->status_report_request_lock);
reinit_completion(&priv->status_report_received);
spin_unlock_bh(&priv->status_report_request_lock);
/* 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;
return 0;
}
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);
priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
priv->hdev = hdev;
hid_set_drvdata(hdev, priv);
/* * Initialize priv->updated to STATUS_VALIDITY seconds in the past, making * the initial empty data invalid for waterforce_read() without the need for * a special case there.
*/
priv->updated = jiffies - msecs_to_jiffies(STATUS_VALIDITY);
ret = hid_parse(hdev); if (ret) {
hid_err(hdev, "hid parse failed with %d\n", ret); return ret;
}
/* * Enable hidraw so existing user-space tools can continue to work.
*/
ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); if (ret) {
hid_err(hdev, "hid hw start failed with %d\n", ret); return ret;
}
ret = hid_hw_open(hdev); if (ret) {
hid_err(hdev, "hid hw open failed with %d\n", ret); goto fail_and_stop;
}
priv->buffer = devm_kzalloc(&hdev->dev, MAX_REPORT_LENGTH, GFP_KERNEL); if (!priv->buffer) {
ret = -ENOMEM; goto fail_and_close;
}
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.