[PATCH 1/3] platform/x86: x86-android-tablets: Describe Yoga Book haptics
From: Maurizio Casciano
Date: Wed Aug 26 2026 - 09:24:07 EST
ACPI enumerates the Yoga Book YB1-X91F/L haptic controllers as
DRV2604:00 and DRV2604:01, but omits the mode and waveform-library
properties required by drv260x. Both use LRA mode with the empty library.
Attach managed software-node properties to the existing I2C devices.
Hold references until removal, reprobe after adding properties to cover
an earlier built-in probe, and remove the nodes in reverse order.
This has a runtime dependency on the drv260x optional-vbat change.
Functional haptic feedback remains a hardware validation requirement.
Signed-off-by: Maurizio Casciano <mauriziocasciano7@xxxxxxxxx>
Assisted-by: LLM sparse
---
.../platform/x86/x86-android-tablets/lenovo.c | 67 +++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/drivers/platform/x86/x86-android-tablets/lenovo.c b/drivers/platform/x86/x86-android-tablets/lenovo.c
index 8d825e0b4661..413d3633b2e6 100644
--- a/drivers/platform/x86/x86-android-tablets/lenovo.c
+++ b/drivers/platform/x86/x86-android-tablets/lenovo.c
@@ -114,6 +114,12 @@ static const struct software_node lenovo_yb1_x90_hideep_ts_node = {
.properties = lenovo_yb1_x90_hideep_ts_props,
};
+static const struct property_entry lenovo_yb1_x91_drv2604_props[] = {
+ PROPERTY_ENTRY_U32("mode", 0), /* DRV260X_LRA_MODE */
+ PROPERTY_ENTRY_U32("library-sel", 0), /* DRV260X_LIB_EMPTY */
+ { }
+};
+
static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst = {
{
/* BQ27542 fuel-gauge */
@@ -283,9 +289,70 @@ static const struct x86_i2c_client_info lenovo_yogabook_x91_i2c_clients[] __init
},
};
+#define YB1_X91_DRV2604_0_DEVICE "i2c-DRV2604:00"
+#define YB1_X91_DRV2604_1_DEVICE "i2c-DRV2604:01"
+
+static struct device *lenovo_yb1_x91_drv2604_devs[2];
+
+static void lenovo_yb1_x91_add_haptics_props(struct device *dev, int index,
+ const char *name)
+{
+ struct device *haptics_dev;
+ int ret;
+
+ haptics_dev = bus_find_device_by_name(&i2c_bus_type, NULL, name);
+ if (!haptics_dev) {
+ dev_warn(dev, "cannot find %s, haptics will be unavailable\n", name);
+ return;
+ }
+
+ ret = device_create_managed_software_node(haptics_dev,
+ lenovo_yb1_x91_drv2604_props, NULL);
+ if (ret) {
+ put_device(haptics_dev);
+ dev_warn(dev, "failed to add properties to %s: %d\n", name, ret);
+ return;
+ }
+
+ /* Apply the properties if a built-in driver already attempted to probe. */
+ ret = device_reprobe(haptics_dev);
+ if (ret)
+ dev_warn(dev, "failed to reprobe %s: %d\n", name, ret);
+
+ lenovo_yb1_x91_drv2604_devs[index] = haptics_dev;
+}
+
+static void lenovo_yb1_x91_remove_haptics_props(int index)
+{
+ struct device *haptics_dev = lenovo_yb1_x91_drv2604_devs[index];
+
+ if (!haptics_dev)
+ return;
+
+ device_remove_software_node(haptics_dev);
+ put_device(haptics_dev);
+ lenovo_yb1_x91_drv2604_devs[index] = NULL;
+}
+
+static int __init lenovo_yb1_x91_init(struct device *dev)
+{
+ lenovo_yb1_x91_add_haptics_props(dev, 0, YB1_X91_DRV2604_0_DEVICE);
+ lenovo_yb1_x91_add_haptics_props(dev, 1, YB1_X91_DRV2604_1_DEVICE);
+
+ return 0;
+}
+
+static void lenovo_yb1_x91_exit(void)
+{
+ lenovo_yb1_x91_remove_haptics_props(1);
+ lenovo_yb1_x91_remove_haptics_props(0);
+}
+
const struct x86_dev_info lenovo_yogabook_x91_info __initconst = {
.i2c_client_info = lenovo_yogabook_x91_i2c_clients,
.i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x91_i2c_clients),
+ .init = lenovo_yb1_x91_init,
+ .exit = lenovo_yb1_x91_exit,
};
/* Lenovo Yoga Tablet 2 1050F/L's Android factory image has everything hardcoded */
--
2.53.0