Open icevic1 opened 3 years ago
dirty hack - forget the polling mode and use IRQ only:
diff --git a/i2c-hid_standalone/i2c-hid-core.c b/i2c-hid_standalone/i2c-hid-core.c
index f25503f..e663863 100644
--- a/i2c-hid_standalone/i2c-hid-core.c
+++ b/i2c-hid_standalone/i2c-hid-core.c
@@ -841,96 +841,17 @@ struct hid_ll_driver i2c_hid_ll_driver = {
};
EXPORT_SYMBOL_GPL(i2c_hid_ll_driver);
-static int get_gpio_pin_state(struct irq_desc *irq_desc)
-{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(&irq_desc->irq_data);
- int value;
-
- /*
- * This part of code is borrowed from gpiod_get_raw_value_commit in
- * drivers/gpio/gpiolib.c. Ideally, gpiod_get_value_cansleep can be re-used
- * instead but there is no API of converting (struct irq_desc *) to
- * (struct gpio_desc*).
- */
- value = gc->get ? gc->get(gc, irq_desc->irq_data.hwirq) : -EIO;
- value = value < 0 ? value : !!value;
- return value;
-}
-
-static bool interrupt_line_active(struct i2c_hid *ihid)
-{
- int status = get_gpio_pin_state(ihid->irq_desc);
- struct i2c_client *client = ihid->client;
-
- if (status < 0) {
- dev_dbg_ratelimited(&client->dev,
- "Failed to get GPIO Interrupt line status for %s",
- client->name);
- return false;
- }
- /*
- * According to Windows Precsiontion Touchpad's specs
- * https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-precision-touchpad-device-bus-connectivity,
- * GPIO Interrupt Assertion Leve could be either ActiveLow or
- * ActiveHigh.
- */
- if (ihid->irq_trigger_type & IRQF_TRIGGER_LOW)
- return !status;
-
- return status;
-}
-
-static int i2c_hid_polling_thread(void *i2c_hid)
-{
- struct i2c_hid *ihid = i2c_hid;
- unsigned int polling_interval_idle;
-
- while (!kthread_should_stop()) {
- while (interrupt_line_active(i2c_hid) &&
- !test_bit(I2C_HID_READ_PENDING, &ihid->flags) &&
- !kthread_should_stop()) {
- i2c_hid_get_input(ihid);
- usleep_range(polling_interval_active_us,
- polling_interval_active_us + 100);
- }
- /*
- * re-calculate polling_interval_idle
- * so the module parameters polling_interval_idle_ms can be
- * changed dynamically through sysfs as polling_interval_active_us
- */
- polling_interval_idle = polling_interval_idle_ms * 1000;
- usleep_range(polling_interval_idle,
- polling_interval_idle + 1000);
- }
-
- return 0;
-}
-
static int i2c_hid_init_polling(struct i2c_hid *ihid)
{
struct i2c_client *client = ihid->client;
- ihid->irq_trigger_type = irq_get_trigger_type(client->irq);
- if (!ihid->irq_trigger_type) {
- dev_dbg(&client->dev,
- "Failed to get GPIO Interrupt Assertion Level, could not enable polling mode for %s",
- client->name);
- return -EINVAL;
- }
-
- ihid->polling_thread = kthread_create(i2c_hid_polling_thread, ihid,
- "I2C HID polling thread");
-
- if (IS_ERR(ihid->polling_thread)) {
- dev_err(&client->dev, "Failed to create I2C HID polling thread");
- return PTR_ERR(ihid->polling_thread);
- }
-
- ihid->irq_desc = irq_to_desc(client->irq);
- wake_up_process(ihid->polling_thread);
- return 0;
+ dev_dbg(&client->dev,
+ "Could not enable polling mode for %s",
+ client->name);
+ return -EINVAL;
}
+
static int i2c_hid_init_irq(struct i2c_client *client)
{
struct i2c_hid *ihid = i2c_get_clientdata(client);
$ make