Commit 5512c33c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'hwmon-for-v6.5-rc6' of...

Merge tag 'hwmon-for-v6.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon fixes from Guenter Roeck:

 - Fix sporadic comunication errors in pmbus/bel-pfe and
   aquacomputer_d5next drivers

* tag 'hwmon-for-v6.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
  hwmon: (aquacomputer_d5next) Add selective 200ms delay after sending ctrl report
  hwmon: (pmbus/bel-pfe) Enable PMBUS_SKIP_STATUS_CHECK for pfe1100
parents 190bf7b1 56b930dc
...@@ -13,9 +13,11 @@ ...@@ -13,9 +13,11 @@
#include <linux/crc16.h> #include <linux/crc16.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/hid.h> #include <linux/hid.h>
#include <linux/hwmon.h> #include <linux/hwmon.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/ktime.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
...@@ -63,6 +65,8 @@ static const char *const aqc_device_names[] = { ...@@ -63,6 +65,8 @@ static const char *const aqc_device_names[] = {
#define CTRL_REPORT_ID 0x03 #define CTRL_REPORT_ID 0x03
#define AQUAERO_CTRL_REPORT_ID 0x0b #define AQUAERO_CTRL_REPORT_ID 0x0b
#define CTRL_REPORT_DELAY 200 /* ms */
/* The HID report that the official software always sends /* The HID report that the official software always sends
* after writing values, currently same for all devices * after writing values, currently same for all devices
*/ */
...@@ -527,6 +531,9 @@ struct aqc_data { ...@@ -527,6 +531,9 @@ struct aqc_data {
int secondary_ctrl_report_size; int secondary_ctrl_report_size;
u8 *secondary_ctrl_report; u8 *secondary_ctrl_report;
ktime_t last_ctrl_report_op;
int ctrl_report_delay; /* Delay between two ctrl report operations, in ms */
int buffer_size; int buffer_size;
u8 *buffer; u8 *buffer;
int checksum_start; int checksum_start;
...@@ -611,17 +618,35 @@ static int aqc_aquastreamxt_convert_fan_rpm(u16 val) ...@@ -611,17 +618,35 @@ static int aqc_aquastreamxt_convert_fan_rpm(u16 val)
return 0; return 0;
} }
static void aqc_delay_ctrl_report(struct aqc_data *priv)
{
/*
* If previous read or write is too close to this one, delay the current operation
* to give the device enough time to process the previous one.
*/
if (priv->ctrl_report_delay) {
s64 delta = ktime_ms_delta(ktime_get(), priv->last_ctrl_report_op);
if (delta < priv->ctrl_report_delay)
msleep(priv->ctrl_report_delay - delta);
}
}
/* Expects the mutex to be locked */ /* Expects the mutex to be locked */
static int aqc_get_ctrl_data(struct aqc_data *priv) static int aqc_get_ctrl_data(struct aqc_data *priv)
{ {
int ret; int ret;
aqc_delay_ctrl_report(priv);
memset(priv->buffer, 0x00, priv->buffer_size); memset(priv->buffer, 0x00, priv->buffer_size);
ret = hid_hw_raw_request(priv->hdev, priv->ctrl_report_id, priv->buffer, priv->buffer_size, ret = hid_hw_raw_request(priv->hdev, priv->ctrl_report_id, priv->buffer, priv->buffer_size,
HID_FEATURE_REPORT, HID_REQ_GET_REPORT); HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
if (ret < 0) if (ret < 0)
ret = -ENODATA; ret = -ENODATA;
priv->last_ctrl_report_op = ktime_get();
return ret; return ret;
} }
...@@ -631,6 +656,8 @@ static int aqc_send_ctrl_data(struct aqc_data *priv) ...@@ -631,6 +656,8 @@ static int aqc_send_ctrl_data(struct aqc_data *priv)
int ret; int ret;
u16 checksum; u16 checksum;
aqc_delay_ctrl_report(priv);
/* Checksum is not needed for Aquaero */ /* Checksum is not needed for Aquaero */
if (priv->kind != aquaero) { if (priv->kind != aquaero) {
/* Init and xorout value for CRC-16/USB is 0xffff */ /* Init and xorout value for CRC-16/USB is 0xffff */
...@@ -646,12 +673,16 @@ static int aqc_send_ctrl_data(struct aqc_data *priv) ...@@ -646,12 +673,16 @@ static int aqc_send_ctrl_data(struct aqc_data *priv)
ret = hid_hw_raw_request(priv->hdev, priv->ctrl_report_id, priv->buffer, priv->buffer_size, ret = hid_hw_raw_request(priv->hdev, priv->ctrl_report_id, priv->buffer, priv->buffer_size,
HID_FEATURE_REPORT, HID_REQ_SET_REPORT); HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
if (ret < 0) if (ret < 0)
return ret; goto record_access_and_ret;
/* The official software sends this report after every change, so do it here as well */ /* The official software sends this report after every change, so do it here as well */
ret = hid_hw_raw_request(priv->hdev, priv->secondary_ctrl_report_id, ret = hid_hw_raw_request(priv->hdev, priv->secondary_ctrl_report_id,
priv->secondary_ctrl_report, priv->secondary_ctrl_report_size, priv->secondary_ctrl_report, priv->secondary_ctrl_report_size,
HID_FEATURE_REPORT, HID_REQ_SET_REPORT); HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
record_access_and_ret:
priv->last_ctrl_report_op = ktime_get();
return ret; return ret;
} }
...@@ -1524,6 +1555,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -1524,6 +1555,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->buffer_size = AQUAERO_CTRL_REPORT_SIZE; priv->buffer_size = AQUAERO_CTRL_REPORT_SIZE;
priv->temp_ctrl_offset = AQUAERO_TEMP_CTRL_OFFSET; priv->temp_ctrl_offset = AQUAERO_TEMP_CTRL_OFFSET;
priv->ctrl_report_delay = CTRL_REPORT_DELAY;
priv->temp_label = label_temp_sensors; priv->temp_label = label_temp_sensors;
priv->virtual_temp_label = label_virtual_temp_sensors; priv->virtual_temp_label = label_virtual_temp_sensors;
...@@ -1547,6 +1579,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -1547,6 +1579,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->temp_ctrl_offset = D5NEXT_TEMP_CTRL_OFFSET; priv->temp_ctrl_offset = D5NEXT_TEMP_CTRL_OFFSET;
priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE; priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE;
priv->ctrl_report_delay = CTRL_REPORT_DELAY;
priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES; priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES;
...@@ -1597,6 +1630,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -1597,6 +1630,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->temp_ctrl_offset = OCTO_TEMP_CTRL_OFFSET; priv->temp_ctrl_offset = OCTO_TEMP_CTRL_OFFSET;
priv->buffer_size = OCTO_CTRL_REPORT_SIZE; priv->buffer_size = OCTO_CTRL_REPORT_SIZE;
priv->ctrl_report_delay = CTRL_REPORT_DELAY;
priv->power_cycle_count_offset = OCTO_POWER_CYCLES; priv->power_cycle_count_offset = OCTO_POWER_CYCLES;
...@@ -1624,6 +1658,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -1624,6 +1658,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET; priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET;
priv->buffer_size = QUADRO_CTRL_REPORT_SIZE; priv->buffer_size = QUADRO_CTRL_REPORT_SIZE;
priv->ctrl_report_delay = CTRL_REPORT_DELAY;
priv->flow_pulses_ctrl_offset = QUADRO_FLOW_PULSES_CTRL_OFFSET; priv->flow_pulses_ctrl_offset = QUADRO_FLOW_PULSES_CTRL_OFFSET;
priv->power_cycle_count_offset = QUADRO_POWER_CYCLES; priv->power_cycle_count_offset = QUADRO_POWER_CYCLES;
......
...@@ -17,12 +17,13 @@ ...@@ -17,12 +17,13 @@
enum chips {pfe1100, pfe3000}; enum chips {pfe1100, pfe3000};
/* /*
* Disable status check for pfe3000 devices, because some devices report * Disable status check because some devices report communication error
* communication error (invalid command) for VOUT_MODE command (0x20) * (invalid command) for VOUT_MODE command (0x20) although the correct
* although correct VOUT_MODE (0x16) is returned: it leads to incorrect * VOUT_MODE (0x16) is returned: it leads to incorrect exponent in linear
* exponent in linear mode. * mode.
* This affects both pfe3000 and pfe1100.
*/ */
static struct pmbus_platform_data pfe3000_plat_data = { static struct pmbus_platform_data pfe_plat_data = {
.flags = PMBUS_SKIP_STATUS_CHECK, .flags = PMBUS_SKIP_STATUS_CHECK,
}; };
...@@ -94,16 +95,15 @@ static int pfe_pmbus_probe(struct i2c_client *client) ...@@ -94,16 +95,15 @@ static int pfe_pmbus_probe(struct i2c_client *client)
int model; int model;
model = (int)i2c_match_id(pfe_device_id, client)->driver_data; model = (int)i2c_match_id(pfe_device_id, client)->driver_data;
client->dev.platform_data = &pfe_plat_data;
/* /*
* PFE3000-12-069RA devices may not stay in page 0 during device * PFE3000-12-069RA devices may not stay in page 0 during device
* probe which leads to probe failure (read status word failed). * probe which leads to probe failure (read status word failed).
* So let's set the device to page 0 at the beginning. * So let's set the device to page 0 at the beginning.
*/ */
if (model == pfe3000) { if (model == pfe3000)
client->dev.platform_data = &pfe3000_plat_data;
i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
}
return pmbus_do_probe(client, &pfe_driver_info[model]); return pmbus_do_probe(client, &pfe_driver_info[model]);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment