summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.com>2026-04-16 21:06:51 +0200
committerJiri Kosina <jkosina@suse.com>2026-04-16 21:06:51 +0200
commita3922c8393290da840d4a5dd7313a7e44d918b08 (patch)
tree5d703ab3702e2f3fcbb3ee552027f394d9707965 /drivers
parent38d76018bb412dc66b08837097eff53d21e8df29 (diff)
parentac977b900907f621e117184e71766f297a2f702b (diff)
Merge branch 'for-7.1/mcp2221' into for-linus
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/hid-mcp2221.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
index ef3b5c77c38e..be80970ab48e 100644
--- a/drivers/hid/hid-mcp2221.c
+++ b/drivers/hid/hid-mcp2221.c
@@ -19,8 +19,15 @@
#include <linux/gpio/driver.h>
#include <linux/iio/iio.h>
#include <linux/minmax.h>
+#include <linux/moduleparam.h>
#include "hid-ids.h"
+static bool gpio_mode_enforce;
+
+module_param(gpio_mode_enforce, bool, 0644);
+MODULE_PARM_DESC(gpio_mode_enforce,
+ "Enforce GPIO mode for GP0 thru GP3 (default: false, will be used for IIO)");
+
/* Commands codes in a raw output report */
enum {
MCP2221_I2C_WR_DATA = 0x90,
@@ -536,10 +543,10 @@ static int mcp_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
if (ret)
goto exit;
- mcp->rxbuf_idx = 0;
- mcp->rxbuf = data->block;
- mcp->txbuf[0] = MCP2221_I2C_GET_DATA;
- ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
+ ret = mcp_i2c_smbus_read(mcp, NULL,
+ MCP2221_I2C_RD_RPT_START,
+ addr, data->block[0] + 1,
+ data->block);
if (ret)
goto exit;
} else {
@@ -555,14 +562,14 @@ static int mcp_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
case I2C_SMBUS_I2C_BLOCK_DATA:
if (read_write == I2C_SMBUS_READ) {
ret = mcp_smbus_write(mcp, addr, command, NULL,
- 0, MCP2221_I2C_WR_NO_STOP, 1);
+ 0, MCP2221_I2C_WR_NO_STOP, 0);
if (ret)
goto exit;
- mcp->rxbuf_idx = 0;
- mcp->rxbuf = data->block;
- mcp->txbuf[0] = MCP2221_I2C_GET_DATA;
- ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
+ ret = mcp_i2c_smbus_read(mcp, NULL,
+ MCP2221_I2C_RD_RPT_START,
+ addr, data->block[0],
+ &data->block[1]);
if (ret)
goto exit;
} else {
@@ -650,7 +657,7 @@ static int mcp2221_check_gpio_pinfunc(struct mcp2221 *mcp)
int needgpiofix = 0;
int ret;
- if (IS_ENABLED(CONFIG_IIO))
+ if (IS_ENABLED(CONFIG_IIO) && !gpio_mode_enforce)
return 0;
ret = mcp_gpio_read_sram(mcp);
@@ -1045,7 +1052,8 @@ static void mcp2221_remove(struct hid_device *hdev)
#if IS_REACHABLE(CONFIG_IIO)
struct mcp2221 *mcp = hid_get_drvdata(hdev);
- cancel_delayed_work_sync(&mcp->init_work);
+ if (!gpio_mode_enforce)
+ cancel_delayed_work_sync(&mcp->init_work);
#endif
}
@@ -1319,8 +1327,10 @@ static int mcp2221_probe(struct hid_device *hdev,
#endif
#if IS_REACHABLE(CONFIG_IIO)
- INIT_DELAYED_WORK(&mcp->init_work, mcp_init_work);
- schedule_delayed_work(&mcp->init_work, msecs_to_jiffies(100));
+ if (!gpio_mode_enforce) {
+ INIT_DELAYED_WORK(&mcp->init_work, mcp_init_work);
+ schedule_delayed_work(&mcp->init_work, msecs_to_jiffies(100));
+ }
#endif
return 0;