hwmon fixes for v6.5-rc6
* Fix sporadic comunication errors in pmbus/bel-pfe and aquacomputer_d5next drivers -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEiHPvMQj9QTOCiqgVyx8mb86fmYEFAmTWvZUACgkQyx8mb86f mYGwjA/+OsXkdz90jsZ+JdJSUuqWsr5kGwEEWHZzPFizxnHw8/EeMiEdhwPwN8Wm SBlqXPWs0FiAZaQ/oWJEXPg0Lw6hQ8uIAds99USUpYWu0uQMyg6GeIq+14u+EbR0 LpvjVr/TY4x4v6KeQBHxUfhc2b7x9Tk+XfUFs2m21nnv+TmrvWONqKVCXCYmKXTQ f0wrErxcznwguj6aD7CrYQRdXfXk2LX6kgxPqFAlsbBLALceA0OpgnWZrAM00de+ ChnoOxZ+kSfNeZvDk6eXGMJDcR/N7z98y2/qWZNqtGNxhzMUoGKROQlbyovVLbVw dmmThs2IKWLa8CUcQG4tyAYHQr7KoZN+uMdwoMII9+eB5fCC48Po0vqZz993Fxo0 tX5FGZnifigLKL30dpU2q7wfPzdIC/xmbibTjS5klnEFD5zrPPRf1bgsa4EnaPsh 2ZlpiMJLtEM8b1LjjYydhdLoi+EerpHr9wilaiYnhKTnraeD4lQAPCU4yeBYZHza R9mfqgXtfoUzKkiY3odGTfhjsahkUxPn5C0+Dt29ON4hQcLig08UqByDaM2S5PVb qPjBinLaD3/RYPADxMRWJwZvwUkoq7bIWu62mxnPBwmvURz211T4s9Hnfrxo8/fc pUVXlqM2s+5TUuCv3l/Wj8BLtBIPzxOskVdANOw3RlTT2+ymKG0= =z7ER -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
5512c33c7b
@ -13,9 +13,11 @@
|
||||
|
||||
#include <linux/crc16.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/seq_file.h>
|
||||
@ -63,6 +65,8 @@ static const char *const aqc_device_names[] = {
|
||||
#define CTRL_REPORT_ID 0x03
|
||||
#define AQUAERO_CTRL_REPORT_ID 0x0b
|
||||
|
||||
#define CTRL_REPORT_DELAY 200 /* ms */
|
||||
|
||||
/* The HID report that the official software always sends
|
||||
* after writing values, currently same for all devices
|
||||
*/
|
||||
@ -527,6 +531,9 @@ struct aqc_data {
|
||||
int secondary_ctrl_report_size;
|
||||
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;
|
||||
u8 *buffer;
|
||||
int checksum_start;
|
||||
@ -611,17 +618,35 @@ static int aqc_aquastreamxt_convert_fan_rpm(u16 val)
|
||||
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 */
|
||||
static int aqc_get_ctrl_data(struct aqc_data *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
aqc_delay_ctrl_report(priv);
|
||||
|
||||
memset(priv->buffer, 0x00, 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);
|
||||
if (ret < 0)
|
||||
ret = -ENODATA;
|
||||
|
||||
priv->last_ctrl_report_op = ktime_get();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -631,6 +656,8 @@ static int aqc_send_ctrl_data(struct aqc_data *priv)
|
||||
int ret;
|
||||
u16 checksum;
|
||||
|
||||
aqc_delay_ctrl_report(priv);
|
||||
|
||||
/* Checksum is not needed for Aquaero */
|
||||
if (priv->kind != aquaero) {
|
||||
/* Init and xorout value for CRC-16/USB is 0xffff */
|
||||
@ -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,
|
||||
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
|
||||
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 */
|
||||
ret = hid_hw_raw_request(priv->hdev, priv->secondary_ctrl_report_id,
|
||||
priv->secondary_ctrl_report, priv->secondary_ctrl_report_size,
|
||||
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
|
||||
|
||||
record_access_and_ret:
|
||||
priv->last_ctrl_report_op = ktime_get();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -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->temp_ctrl_offset = AQUAERO_TEMP_CTRL_OFFSET;
|
||||
priv->ctrl_report_delay = CTRL_REPORT_DELAY;
|
||||
|
||||
priv->temp_label = label_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)
|
||||
priv->temp_ctrl_offset = D5NEXT_TEMP_CTRL_OFFSET;
|
||||
|
||||
priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE;
|
||||
priv->ctrl_report_delay = CTRL_REPORT_DELAY;
|
||||
|
||||
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)
|
||||
priv->temp_ctrl_offset = OCTO_TEMP_CTRL_OFFSET;
|
||||
|
||||
priv->buffer_size = OCTO_CTRL_REPORT_SIZE;
|
||||
priv->ctrl_report_delay = CTRL_REPORT_DELAY;
|
||||
|
||||
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)
|
||||
priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET;
|
||||
|
||||
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->power_cycle_count_offset = QUADRO_POWER_CYCLES;
|
||||
|
@ -17,12 +17,13 @@
|
||||
enum chips {pfe1100, pfe3000};
|
||||
|
||||
/*
|
||||
* Disable status check for pfe3000 devices, because some devices report
|
||||
* communication error (invalid command) for VOUT_MODE command (0x20)
|
||||
* although correct VOUT_MODE (0x16) is returned: it leads to incorrect
|
||||
* exponent in linear mode.
|
||||
* Disable status check because some devices report communication error
|
||||
* (invalid command) for VOUT_MODE command (0x20) although the correct
|
||||
* VOUT_MODE (0x16) is returned: it leads to incorrect exponent in linear
|
||||
* 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,
|
||||
};
|
||||
|
||||
@ -94,16 +95,15 @@ static int pfe_pmbus_probe(struct i2c_client *client)
|
||||
int model;
|
||||
|
||||
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
|
||||
* probe which leads to probe failure (read status word failed).
|
||||
* So let's set the device to page 0 at the beginning.
|
||||
*/
|
||||
if (model == pfe3000) {
|
||||
client->dev.platform_data = &pfe3000_plat_data;
|
||||
if (model == pfe3000)
|
||||
i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
|
||||
}
|
||||
|
||||
return pmbus_do_probe(client, &pfe_driver_info[model]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user