Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH v3 03/10] HID: steam: Rename some constants that got renamed upstream
From: Vicki Pfau @ 2026-07-10  2:00 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, linux-input; +Cc: Vicki Pfau, Yousef Alhouseen
In-Reply-To: <20260710020048.2337655-1-vi@endrift.com>

SETTING_MOUSE_POINTER_ENABLED was renamed to SETTING_LIZARD_MODE upstream.
SETTING_GYRO_MODE was renamed to SETTING_IMU_MODE in an older commit, but
the associated enum was overlooked.

Signed-off-by: Vicki Pfau <vi@endrift.com>
---
 drivers/hid/hid-steam.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index 1b0367c98eac..add9f4f27fff 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -151,7 +151,7 @@ enum {
 	SETTING_USB_DEBUG_MODE,
 	SETTING_LEFT_TRACKPAD_MODE,
 	SETTING_RIGHT_TRACKPAD_MODE,
-	SETTING_MOUSE_POINTER_ENABLED,
+	SETTING_LIZARD_MODE,
 
 	/* 10 */
 	SETTING_DPAD_DEADZONE,
@@ -261,14 +261,14 @@ enum {
 	ATTRIB_STR_UNIT_SERIAL,
 };
 
-/* Values for GYRO_MODE (bitmask) */
+/* Values for IMU_MODE (bitmask) */
 enum {
-	SETTING_GYRO_MODE_OFF			= 0,
-	SETTING_GYRO_MODE_STEERING		= BIT(0),
-	SETTING_GYRO_MODE_TILT			= BIT(1),
-	SETTING_GYRO_MODE_SEND_ORIENTATION	= BIT(2),
-	SETTING_GYRO_MODE_SEND_RAW_ACCEL	= BIT(3),
-	SETTING_GYRO_MODE_SEND_RAW_GYRO		= BIT(4),
+	SETTING_IMU_MODE_OFF			= 0,
+	SETTING_IMU_MODE_STEERING		= BIT(0),
+	SETTING_IMU_MODE_TILT			= BIT(1),
+	SETTING_IMU_MODE_SEND_ORIENTATION	= BIT(2),
+	SETTING_IMU_MODE_SEND_RAW_ACCEL		= BIT(3),
+	SETTING_IMU_MODE_SEND_RAW_GYRO		= BIT(4),
 };
 
 /* Trackpad modes */
-- 
2.54.0


^ permalink raw reply related

* [PATCH v3 04/10] HID: steam: Add support for sensor events on the Steam Controller (2015)
From: Vicki Pfau @ 2026-07-10  2:00 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, linux-input; +Cc: Vicki Pfau, Yousef Alhouseen
In-Reply-To: <20260710020048.2337655-1-vi@endrift.com>

Sensor support was added for the Steam Deck previously, but Steam
Controller sensor events were never added. This adds that missing support,
bringing Steam Controller support much closer to feature parity with things
like SDL and Steam itself.

Signed-off-by: Vicki Pfau <vi@endrift.com>
---
 drivers/hid/hid-steam.c | 214 ++++++++++++++++++++++++++++++++--------
 1 file changed, 175 insertions(+), 39 deletions(-)

diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index add9f4f27fff..6029c055a6cf 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -70,13 +70,14 @@ static LIST_HEAD(steam_devices);
 /* Joystick runs are about 5 mm and 32768 units */
 #define STEAM_DECK_JOYSTICK_RESOLUTION 6553
 /* Accelerometer has 16 bit resolution and a range of +/- 2g */
-#define STEAM_DECK_ACCEL_RES_PER_G 16384
-#define STEAM_DECK_ACCEL_RANGE 32768
+#define STEAM_ACCEL_RES_PER_G 16384
+#define STEAM_ACCEL_RANGE 32768
+#define STEAM_ACCEL_FUZZ 128
 #define STEAM_DECK_ACCEL_FUZZ 32
 /* Gyroscope has 16 bit resolution and a range of +/- 2000 dps */
-#define STEAM_DECK_GYRO_RES_PER_DPS 16
-#define STEAM_DECK_GYRO_RANGE 32768
-#define STEAM_DECK_GYRO_FUZZ 1
+#define STEAM_GYRO_RES_PER_DPS 16
+#define STEAM_GYRO_RANGE 32768
+#define STEAM_GYRO_FUZZ 0
 
 #define STEAM_PAD_FUZZ 256
 
@@ -255,6 +256,31 @@ enum
 	ID_CONTROLLER_DECK_STATE = 9
 };
 
+/* Read-only attributes */
+enum {
+	ATTRIB_UNIQUE_ID, // deprecated
+	ATTRIB_PRODUCT_ID,
+	ATTRIB_PRODUCT_REVISON, // deprecated
+	ATTRIB_CAPABILITIES = ATTRIB_PRODUCT_REVISON, // intentional aliasing
+	ATTRIB_FIRMWARE_VERSION, // deprecated
+	ATTRIB_FIRMWARE_BUILD_TIME,
+	ATTRIB_RADIO_FIRMWARE_BUILD_TIME,
+	ATTRIB_RADIO_DEVICE_ID0,
+	ATTRIB_RADIO_DEVICE_ID1,
+	ATTRIB_DONGLE_FIRMWARE_BUILD_TIME,
+	ATTRIB_HW_ID, // AKA BOARD_REVISION,
+	ATTRIB_BOOTLOADER_BUILD_TIME,
+	ATTRIB_CONNECTION_INTERVAL_IN_US,
+	ATTRIB_SECONDARY_FIRMWARE_BUILD_TIME,
+	ATTRIB_SECONDARY_BOOTLOADER_BUILD_TIME,
+	ATTRIB_SECONDARY_HW_ID, // AKA BOARD_REVISION,
+	ATTRIB_STREAMING,
+	ATTRIB_TRACKPAD_ID,
+	ATTRIB_SECONDARY_TRACKPAD_ID,
+
+	ATTRIB_COUNT
+};
+
 /* String attribute identifiers */
 enum {
 	ATTRIB_STR_BOARD_SERIAL,
@@ -284,6 +310,11 @@ enum {
 	TRACKPAD_GESTURE_KEYBOARD,
 };
 
+struct steam_controller_attribute {
+	unsigned char tag;
+	__le32 value;
+} __packed;
+
 /* Pad identifiers for the deck */
 #define STEAM_PAD_LEFT 0
 #define STEAM_PAD_RIGHT 1
@@ -315,6 +346,7 @@ struct steam_device {
 	u16 rumble_left;
 	u16 rumble_right;
 	unsigned int sensor_timestamp_us;
+	unsigned int sensor_update_rate_us;
 	struct work_struct unregister_work;
 };
 
@@ -468,6 +500,38 @@ static int steam_get_serial(struct steam_device *steam)
 	return ret;
 }
 
+static int steam_get_attributes(struct steam_device *steam)
+{
+	int ret = 0;
+	u8 cmd[] = {ID_GET_ATTRIBUTES_VALUES, 0};
+	u8 reply[64] = {};
+	u8 size;
+	int i;
+	struct steam_controller_attribute *attr;
+
+	guard(mutex)(&steam->report_mutex);
+	ret = steam_send_report(steam, cmd, sizeof(cmd));
+	if (ret < 0)
+		return ret;
+	ret = steam_recv_report(steam, reply, sizeof(reply));
+	if (ret < 0)
+		return ret;
+	if (reply[0] != ID_GET_ATTRIBUTES_VALUES || reply[1] < 2)
+		return -EIO;
+
+	size = min(reply[1], sizeof(reply) - 2);
+	for (i = 0; i + sizeof(*attr) <= size; i += sizeof(*attr)) {
+		attr = (struct steam_controller_attribute *)&reply[i + 2];
+		if (attr->tag == ATTRIB_CONNECTION_INTERVAL_IN_US) {
+			steam->sensor_update_rate_us = get_unaligned_le32(&attr->value);
+			hid_dbg(steam->hdev, "Sensor update rate: %uus\n",
+				steam->sensor_update_rate_us);
+		}
+	}
+
+	return 0;
+}
+
 /*
  * This command requests the wireless adaptor to post an event
  * with the connection status. Useful if this driver is loaded when
@@ -626,6 +690,42 @@ static void steam_input_close(struct input_dev *dev)
 	}
 }
 
+static int steam_sensor_open(struct input_dev *dev)
+{
+	struct steam_device *steam = input_get_drvdata(dev);
+	unsigned long flags;
+	bool client_opened;
+
+	spin_lock_irqsave(&steam->lock, flags);
+	client_opened = steam->client_opened;
+	spin_unlock_irqrestore(&steam->lock, flags);
+	if (client_opened)
+		return 0;
+
+	guard(mutex)(&steam->report_mutex);
+	steam_write_settings(steam, SETTING_IMU_MODE,
+			SETTING_IMU_MODE_SEND_RAW_ACCEL | SETTING_IMU_MODE_SEND_RAW_GYRO,
+			0);
+
+	return 0;
+}
+
+static void steam_sensor_close(struct input_dev *dev)
+{
+	struct steam_device *steam = input_get_drvdata(dev);
+	unsigned long flags;
+	bool client_opened;
+
+	spin_lock_irqsave(&steam->lock, flags);
+	client_opened = steam->client_opened;
+	spin_unlock_irqrestore(&steam->lock, flags);
+	if (client_opened)
+		return;
+
+	guard(mutex)(&steam->report_mutex);
+	steam_write_settings(steam, SETTING_IMU_MODE, 0, 0);
+}
+
 static enum power_supply_property steam_battery_props[] = {
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_SCOPE,
@@ -839,9 +939,6 @@ static int steam_sensors_register(struct steam_device *steam)
 	struct input_dev *sensors;
 	int ret;
 
-	if (!(steam->quirks & STEAM_QUIRK_DECK))
-		return 0;
-
 	rcu_read_lock();
 	sensors = rcu_dereference(steam->sensors);
 	rcu_read_unlock();
@@ -856,8 +953,14 @@ static int steam_sensors_register(struct steam_device *steam)
 
 	input_set_drvdata(sensors, steam);
 	sensors->dev.parent = &hdev->dev;
+	if (!(steam->quirks & STEAM_QUIRK_DECK)) {
+		sensors->open = steam_sensor_open;
+		sensors->close = steam_sensor_close;
+	}
 
-	sensors->name = "Steam Deck Motion Sensors";
+	sensors->name = steam->quirks & STEAM_QUIRK_DECK ?
+		"Steam Deck Motion Sensors" :
+		"Steam Controller Motion Sensors";
 	sensors->phys = hdev->phys;
 	sensors->uniq = steam->serial_no;
 	sensors->id.bustype = hdev->bus;
@@ -869,25 +972,34 @@ static int steam_sensors_register(struct steam_device *steam)
 	__set_bit(EV_MSC, sensors->evbit);
 	__set_bit(MSC_TIMESTAMP, sensors->mscbit);
 
-	input_set_abs_params(sensors, ABS_X, -STEAM_DECK_ACCEL_RANGE,
-			STEAM_DECK_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0);
-	input_set_abs_params(sensors, ABS_Y, -STEAM_DECK_ACCEL_RANGE,
-			STEAM_DECK_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0);
-	input_set_abs_params(sensors, ABS_Z, -STEAM_DECK_ACCEL_RANGE,
-			STEAM_DECK_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0);
-	input_abs_set_res(sensors, ABS_X, STEAM_DECK_ACCEL_RES_PER_G);
-	input_abs_set_res(sensors, ABS_Y, STEAM_DECK_ACCEL_RES_PER_G);
-	input_abs_set_res(sensors, ABS_Z, STEAM_DECK_ACCEL_RES_PER_G);
-
-	input_set_abs_params(sensors, ABS_RX, -STEAM_DECK_GYRO_RANGE,
-			STEAM_DECK_GYRO_RANGE, STEAM_DECK_GYRO_FUZZ, 0);
-	input_set_abs_params(sensors, ABS_RY, -STEAM_DECK_GYRO_RANGE,
-			STEAM_DECK_GYRO_RANGE, STEAM_DECK_GYRO_FUZZ, 0);
-	input_set_abs_params(sensors, ABS_RZ, -STEAM_DECK_GYRO_RANGE,
-			STEAM_DECK_GYRO_RANGE, STEAM_DECK_GYRO_FUZZ, 0);
-	input_abs_set_res(sensors, ABS_RX, STEAM_DECK_GYRO_RES_PER_DPS);
-	input_abs_set_res(sensors, ABS_RY, STEAM_DECK_GYRO_RES_PER_DPS);
-	input_abs_set_res(sensors, ABS_RZ, STEAM_DECK_GYRO_RES_PER_DPS);
+	if (steam->quirks & STEAM_QUIRK_DECK) {
+		input_set_abs_params(sensors, ABS_X, -STEAM_ACCEL_RANGE,
+				STEAM_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0);
+		input_set_abs_params(sensors, ABS_Y, -STEAM_ACCEL_RANGE,
+				STEAM_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0);
+		input_set_abs_params(sensors, ABS_Z, -STEAM_ACCEL_RANGE,
+				STEAM_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0);
+	} else {
+		input_set_abs_params(sensors, ABS_X, -STEAM_ACCEL_RANGE,
+				STEAM_ACCEL_RANGE, STEAM_ACCEL_FUZZ, 0);
+		input_set_abs_params(sensors, ABS_Y, -STEAM_ACCEL_RANGE,
+				STEAM_ACCEL_RANGE, STEAM_ACCEL_FUZZ, 0);
+		input_set_abs_params(sensors, ABS_Z, -STEAM_ACCEL_RANGE,
+				STEAM_ACCEL_RANGE, STEAM_ACCEL_FUZZ, 0);
+	}
+	input_abs_set_res(sensors, ABS_X, STEAM_ACCEL_RES_PER_G);
+	input_abs_set_res(sensors, ABS_Y, STEAM_ACCEL_RES_PER_G);
+	input_abs_set_res(sensors, ABS_Z, STEAM_ACCEL_RES_PER_G);
+
+	input_set_abs_params(sensors, ABS_RX, -STEAM_GYRO_RANGE,
+			STEAM_GYRO_RANGE, STEAM_GYRO_FUZZ, 0);
+	input_set_abs_params(sensors, ABS_RY, -STEAM_GYRO_RANGE,
+			STEAM_GYRO_RANGE, STEAM_GYRO_FUZZ, 0);
+	input_set_abs_params(sensors, ABS_RZ, -STEAM_GYRO_RANGE,
+			STEAM_GYRO_RANGE, STEAM_GYRO_FUZZ, 0);
+	input_abs_set_res(sensors, ABS_RX, STEAM_GYRO_RES_PER_DPS);
+	input_abs_set_res(sensors, ABS_RY, STEAM_GYRO_RES_PER_DPS);
+	input_abs_set_res(sensors, ABS_RZ, STEAM_GYRO_RES_PER_DPS);
 
 	ret = input_register_device(sensors);
 	if (ret)
@@ -918,9 +1030,6 @@ static void steam_sensors_unregister(struct steam_device *steam)
 {
 	struct input_dev *sensors;
 
-	if (!(steam->quirks & STEAM_QUIRK_DECK))
-		return;
-
 	rcu_read_lock();
 	sensors = rcu_dereference(steam->sensors);
 	rcu_read_unlock();
@@ -968,6 +1077,12 @@ static int steam_register(struct steam_device *steam)
 			strscpy(steam->serial_no, "XXXXXXXXXX",
 					sizeof(steam->serial_no));
 
+		ret = steam_get_attributes(steam);
+		if (ret < 0)
+			hid_err(steam->hdev,
+				"%s:steam_get_attributes failed with error %d\n",
+				__func__, ret);
+
 		hid_info(steam->hdev, "Steam Controller '%s' connected",
 				steam->serial_no);
 
@@ -1246,6 +1361,10 @@ static int steam_probe(struct hid_device *hdev,
 	INIT_LIST_HEAD(&steam->list);
 	INIT_WORK(&steam->rumble_work, steam_haptic_rumble_cb);
 	steam->sensor_timestamp_us = 0;
+	if (steam->quirks & STEAM_QUIRK_DECK)
+		steam->sensor_update_rate_us = 4000;
+	else
+		steam->sensor_update_rate_us = 9000;
 	INIT_WORK(&steam->unregister_work, steam_work_unregister_cb);
 
 	/*
@@ -1491,6 +1610,16 @@ static const struct steam_axis_mapping steam_controller_axis_mappings[] = {
 	{ /* sentinel */ },
 };
 
+static const struct steam_axis_mapping steam_controller_imu_mappings[] = {
+	{ ABS_X,   1, 28 },
+	{ ABS_Z,  -1, 30 },
+	{ ABS_Y,   1, 32 },
+	{ ABS_RX,  1, 34 },
+	{ ABS_RZ,  1, 36 },
+	{ ABS_RY,  1, 38 },
+	{ /* sentinel */ },
+};
+
 static void steam_do_input_event(struct steam_device *steam,
 		struct input_dev *input, u8 *data)
 {
@@ -1533,6 +1662,17 @@ static void steam_do_input_event(struct steam_device *steam,
 	input_sync(input);
 }
 
+static void steam_do_sensors_event(struct steam_device *steam,
+		struct input_dev *sensors, u8 *data)
+{
+	steam->sensor_timestamp_us += steam->sensor_update_rate_us;
+
+	input_event(sensors, EV_MSC, MSC_TIMESTAMP, steam->sensor_timestamp_us);
+	steam_map_axes(sensors, steam_controller_imu_mappings, data);
+
+	input_sync(sensors);
+}
+
 /*
  * The size for this message payload is 56.
  * The known values are:
@@ -1727,14 +1867,7 @@ static void steam_do_deck_input_event(struct steam_device *steam,
 static void steam_do_deck_sensors_event(struct steam_device *steam,
 		struct input_dev *sensors, u8 *data)
 {
-	/*
-	 * The deck input report is received every 4 ms on average,
-	 * with a jitter of +/- 4 ms even though the USB descriptor claims
-	 * that it uses 1 kHz.
-	 * Since the HID report does not include a sensor timestamp,
-	 * use a fixed increment here.
-	 */
-	steam->sensor_timestamp_us += 4000;
+	steam->sensor_timestamp_us += steam->sensor_update_rate_us;
 
 	if (!steam->gamepad_mode && lizard_mode)
 		return;
@@ -1819,6 +1952,9 @@ static int steam_raw_event(struct hid_device *hdev,
 		input = rcu_dereference(steam->input);
 		if (likely(input))
 			steam_do_input_event(steam, input, data);
+		sensors = rcu_dereference(steam->sensors);
+		if (likely(sensors))
+			steam_do_sensors_event(steam, sensors, data);
 		rcu_read_unlock();
 		break;
 	case ID_CONTROLLER_DECK_STATE:
-- 
2.54.0


^ permalink raw reply related

* [PATCH v3 02/10] HID: steam: Refactor and clean up report parsing
From: Vicki Pfau @ 2026-07-10  2:00 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, linux-input; +Cc: Vicki Pfau, Yousef Alhouseen
In-Reply-To: <20260710020048.2337655-1-vi@endrift.com>

This switches from a parsing style where each button or axis is parsed
individually out of a report using !!(byte & BIT(x)) style. This commit
switches it to a mostly unified approach of defining a list of individual
mappings in an array and passing it to a function that handles all of the
extraction. Theoretically this is more lines, but in practice it results in
(subjectively) cleaner code. Some exceptions still need to be made for
things like handling the lizard mode toggle key, but in general there's a
lot less manual code.

Signed-off-by: Vicki Pfau <vi@endrift.com>
---
 drivers/hid/hid-steam.c | 211 ++++++++++++++++++++++++----------------
 1 file changed, 128 insertions(+), 83 deletions(-)

diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index a854d6360a0e..1b0367c98eac 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -43,6 +43,7 @@
 #include <linux/rcupdate.h>
 #include <linux/delay.h>
 #include <linux/power_supply.h>
+#include <linux/unaligned.h>
 #include "hid-ids.h"
 
 MODULE_DESCRIPTION("HID driver for Valve Steam Controller");
@@ -1355,13 +1356,45 @@ static void steam_do_connect_event(struct steam_device *steam, bool connected)
  * Clamp the values to 32767..-32767 so that the range is
  * symmetrical and can be negated safely.
  */
-static inline s16 steam_le16(u8 *data)
+static inline s16 steam_le16(const u8 *data)
 {
-	s16 x = (s16) le16_to_cpup((__le16 *)data);
+	s16 x = (s16) get_unaligned_le16((__le16 *)data);
 
 	return x == -32768 ? -32767 : x;
 }
 
+struct steam_button_mapping {
+	int code;
+	u8 byte;
+	u8 bit;
+};
+
+struct steam_axis_mapping {
+	int code;
+	s8 sign;
+	u8 byte;
+};
+
+static void steam_map_buttons(struct input_dev *input,
+		const struct steam_button_mapping *mappings, const u8 *data)
+{
+	const struct steam_button_mapping *mapping;
+
+	for (mapping = mappings; mapping->code; mapping++)
+		input_report_key(input, mapping->code,
+			data[mapping->byte] & BIT(mapping->bit));
+}
+
+static void steam_map_axes(struct input_dev *input,
+		const struct steam_axis_mapping *mappings, const u8 *data)
+{
+	const struct steam_axis_mapping *mapping;
+
+	for (mapping = mappings; mapping->sign; mapping++)
+		input_report_abs(input, mapping->code,
+			mapping->sign * steam_le16(&data[mapping->byte]));
+}
+
 /*
  * The size for this message payload is 60.
  * The known values are:
@@ -1428,18 +1461,42 @@ static inline s16 steam_le16(u8 *data)
  * 10.7  | --         | lpad_and_joy
  */
 
+static const struct steam_button_mapping steam_controller_button_mappings[] = {
+	{ BTN_TR2,		 8, 0 },
+	{ BTN_TL2,		 8, 1 },
+	{ BTN_TR,		 8, 2 },
+	{ BTN_TL,		 8, 3 },
+	{ BTN_Y,		 8, 4 },
+	{ BTN_B,		 8, 5 },
+	{ BTN_X,		 8, 6 },
+	{ BTN_A,		 8, 7 },
+	{ BTN_SELECT,		 9, 4 },
+	{ BTN_MODE,		 9, 5 },
+	{ BTN_START,		 9, 6 },
+	{ BTN_GRIPL,		 9, 7 },
+	{ BTN_GRIPR,		10, 0 },
+	{ BTN_THUMBR,		10, 2 },
+	{ BTN_THUMBL,		10, 6 },
+	{ BTN_THUMB2,		10, 4 },
+	{ BTN_DPAD_UP,		 9, 0 },
+	{ BTN_DPAD_RIGHT,	 9, 1 },
+	{ BTN_DPAD_LEFT,	 9, 2 },
+	{ BTN_DPAD_DOWN,	 9, 3 },
+	{ /* sentinel */ },
+};
+
+static const struct steam_axis_mapping steam_controller_axis_mappings[] = {
+	{ ABS_RX,  1, 20 },
+	{ ABS_RY, -1, 22 },
+	{ /* sentinel */ },
+};
+
 static void steam_do_input_event(struct steam_device *steam,
 		struct input_dev *input, u8 *data)
 {
-	/* 24 bits of buttons */
-	u8 b8, b9, b10;
 	s16 x, y;
 	bool lpad_touched, lpad_and_joy;
 
-	b8 = data[8];
-	b9 = data[9];
-	b10 = data[10];
-
 	input_report_abs(input, ABS_HAT2Y, data[11]);
 	input_report_abs(input, ABS_HAT2X, data[12]);
 
@@ -1451,8 +1508,8 @@ static void steam_do_input_event(struct steam_device *steam,
 	 * joystick values.
 	 * (lpad_touched || lpad_and_joy) tells if the lpad is really touched.
 	 */
-	lpad_touched = b10 & BIT(3);
-	lpad_and_joy = b10 & BIT(7);
+	lpad_touched = data[10] & BIT(3);
+	lpad_and_joy = data[10] & BIT(7);
 	x = steam_le16(data + 16);
 	y = -steam_le16(data + 18);
 
@@ -1468,31 +1525,10 @@ static void steam_do_input_event(struct steam_device *steam,
 		input_report_abs(input, ABS_HAT0X, 0);
 		input_report_abs(input, ABS_HAT0Y, 0);
 	}
+	input_report_key(input, BTN_THUMB, lpad_touched || lpad_and_joy);
 
-	input_report_abs(input, ABS_RX, steam_le16(data + 20));
-	input_report_abs(input, ABS_RY, -steam_le16(data + 22));
-
-	input_event(input, EV_KEY, BTN_TR2, !!(b8 & BIT(0)));
-	input_event(input, EV_KEY, BTN_TL2, !!(b8 & BIT(1)));
-	input_event(input, EV_KEY, BTN_TR, !!(b8 & BIT(2)));
-	input_event(input, EV_KEY, BTN_TL, !!(b8 & BIT(3)));
-	input_event(input, EV_KEY, BTN_Y, !!(b8 & BIT(4)));
-	input_event(input, EV_KEY, BTN_B, !!(b8 & BIT(5)));
-	input_event(input, EV_KEY, BTN_X, !!(b8 & BIT(6)));
-	input_event(input, EV_KEY, BTN_A, !!(b8 & BIT(7)));
-	input_event(input, EV_KEY, BTN_SELECT, !!(b9 & BIT(4)));
-	input_event(input, EV_KEY, BTN_MODE, !!(b9 & BIT(5)));
-	input_event(input, EV_KEY, BTN_START, !!(b9 & BIT(6)));
-	input_event(input, EV_KEY, BTN_GRIPL, !!(b9 & BIT(7)));
-	input_event(input, EV_KEY, BTN_GRIPR, !!(b10 & BIT(0)));
-	input_event(input, EV_KEY, BTN_THUMBR, !!(b10 & BIT(2)));
-	input_event(input, EV_KEY, BTN_THUMBL, !!(b10 & BIT(6)));
-	input_event(input, EV_KEY, BTN_THUMB, lpad_touched || lpad_and_joy);
-	input_event(input, EV_KEY, BTN_THUMB2, !!(b10 & BIT(4)));
-	input_event(input, EV_KEY, BTN_DPAD_UP, !!(b9 & BIT(0)));
-	input_event(input, EV_KEY, BTN_DPAD_RIGHT, !!(b9 & BIT(1)));
-	input_event(input, EV_KEY, BTN_DPAD_LEFT, !!(b9 & BIT(2)));
-	input_event(input, EV_KEY, BTN_DPAD_DOWN, !!(b9 & BIT(3)));
+	steam_map_buttons(input, steam_controller_button_mappings, data);
+	steam_map_axes(input, steam_controller_axis_mappings, data);
 
 	input_sync(input);
 }
@@ -1595,23 +1631,67 @@ static void steam_do_input_event(struct steam_device *steam,
  *  15.6 | --         | unknown
  *  15.7 | --         | unknown
  */
+
+static const struct steam_button_mapping steam_deck_button_mappings[] = {
+	{ BTN_TR2,		 8, 0 },
+	{ BTN_TL2,		 8, 1 },
+	{ BTN_TR,		 8, 2 },
+	{ BTN_TL,		 8, 3 },
+	{ BTN_Y,		 8, 4 },
+	{ BTN_B,		 8, 5 },
+	{ BTN_X,		 8, 6 },
+	{ BTN_A,		 8, 7 },
+	{ BTN_SELECT,		 9, 4 },
+	{ BTN_MODE,		 9, 5 },
+	{ BTN_START,		 9, 6 },
+	{ BTN_GRIPL2,		 9, 7 },
+	{ BTN_GRIPR2,		10, 0 },
+	{ BTN_THUMBL,		10, 6 },
+	{ BTN_THUMBR,		11, 2 },
+	{ BTN_DPAD_UP,		 9, 0 },
+	{ BTN_DPAD_RIGHT,	 9, 1 },
+	{ BTN_DPAD_LEFT,	 9, 2 },
+	{ BTN_DPAD_DOWN,	 9, 3 },
+	{ BTN_THUMB,		10, 1 },
+	{ BTN_THUMB2,		10, 2 },
+	{ BTN_GRIPL,		13, 1 },
+	{ BTN_GRIPR,		13, 2 },
+	{ BTN_BASE,		14, 2 },
+	{ /* sentinel */ },
+};
+
+static const struct steam_axis_mapping steam_deck_axis_mappings[] = {
+	{ ABS_X,	 1, 48 },
+	{ ABS_Y,	-1, 50 },
+	{ ABS_RX,	 1, 52 },
+	{ ABS_RY,	-1, 54 },
+	{ ABS_HAT2Y,	 1, 44 },
+	{ ABS_HAT2X,	 1, 46 },
+	{ /* sentinel */ },
+};
+
+static const struct steam_axis_mapping steam_deck_imu_mappings[] = {
+	{ ABS_X,   1, 24 },
+	{ ABS_Z,  -1, 26 },
+	{ ABS_Y,   1, 28 },
+	{ ABS_RX,  1, 30 },
+	{ ABS_RZ, -1, 32 },
+	{ ABS_RY,  1, 34 },
+	{ /* sentinel */ },
+};
+
 static void steam_do_deck_input_event(struct steam_device *steam,
 		struct input_dev *input, u8 *data)
 {
-	u8 b8, b9, b10, b11, b13, b14;
+	bool start_pressed;
 	bool lpad_touched, rpad_touched;
 
-	b8 = data[8];
-	b9 = data[9];
-	b10 = data[10];
-	b11 = data[11];
-	b13 = data[13];
-	b14 = data[14];
+	start_pressed = data[9] & BIT(6);
 
-	if (!(b9 & BIT(6)) && steam->did_mode_switch) {
+	if (!start_pressed && steam->did_mode_switch) {
 		steam->did_mode_switch = false;
 		cancel_delayed_work(&steam->mode_switch);
-	} else if (!steam->client_opened && (b9 & BIT(6)) && !steam->did_mode_switch) {
+	} else if (!steam->client_opened && start_pressed && !steam->did_mode_switch) {
 		steam->did_mode_switch = true;
 		schedule_delayed_work(&steam->mode_switch, 45 * HZ / 100);
 	}
@@ -1619,8 +1699,8 @@ static void steam_do_deck_input_event(struct steam_device *steam,
 	if (!steam->gamepad_mode && lizard_mode)
 		return;
 
-	lpad_touched = b10 & BIT(3);
-	rpad_touched = b10 & BIT(4);
+	lpad_touched = data[10] & BIT(3);
+	rpad_touched = data[10] & BIT(4);
 
 	if (lpad_touched) {
 		input_report_abs(input, ABS_HAT0X, steam_le16(data + 16));
@@ -1638,38 +1718,8 @@ static void steam_do_deck_input_event(struct steam_device *steam,
 		input_report_abs(input, ABS_HAT1Y, 0);
 	}
 
-	input_report_abs(input, ABS_X, steam_le16(data + 48));
-	input_report_abs(input, ABS_Y, -steam_le16(data + 50));
-	input_report_abs(input, ABS_RX, steam_le16(data + 52));
-	input_report_abs(input, ABS_RY, -steam_le16(data + 54));
-
-	input_report_abs(input, ABS_HAT2Y, steam_le16(data + 44));
-	input_report_abs(input, ABS_HAT2X, steam_le16(data + 46));
-
-	input_event(input, EV_KEY, BTN_TR2, !!(b8 & BIT(0)));
-	input_event(input, EV_KEY, BTN_TL2, !!(b8 & BIT(1)));
-	input_event(input, EV_KEY, BTN_TR, !!(b8 & BIT(2)));
-	input_event(input, EV_KEY, BTN_TL, !!(b8 & BIT(3)));
-	input_event(input, EV_KEY, BTN_Y, !!(b8 & BIT(4)));
-	input_event(input, EV_KEY, BTN_B, !!(b8 & BIT(5)));
-	input_event(input, EV_KEY, BTN_X, !!(b8 & BIT(6)));
-	input_event(input, EV_KEY, BTN_A, !!(b8 & BIT(7)));
-	input_event(input, EV_KEY, BTN_SELECT, !!(b9 & BIT(4)));
-	input_event(input, EV_KEY, BTN_MODE, !!(b9 & BIT(5)));
-	input_event(input, EV_KEY, BTN_START, !!(b9 & BIT(6)));
-	input_event(input, EV_KEY, BTN_GRIPL2, !!(b9 & BIT(7)));
-	input_event(input, EV_KEY, BTN_GRIPR2, !!(b10 & BIT(0)));
-	input_event(input, EV_KEY, BTN_THUMBL, !!(b10 & BIT(6)));
-	input_event(input, EV_KEY, BTN_THUMBR, !!(b11 & BIT(2)));
-	input_event(input, EV_KEY, BTN_DPAD_UP, !!(b9 & BIT(0)));
-	input_event(input, EV_KEY, BTN_DPAD_RIGHT, !!(b9 & BIT(1)));
-	input_event(input, EV_KEY, BTN_DPAD_LEFT, !!(b9 & BIT(2)));
-	input_event(input, EV_KEY, BTN_DPAD_DOWN, !!(b9 & BIT(3)));
-	input_event(input, EV_KEY, BTN_THUMB, !!(b10 & BIT(1)));
-	input_event(input, EV_KEY, BTN_THUMB2, !!(b10 & BIT(2)));
-	input_event(input, EV_KEY, BTN_GRIPL, !!(b13 & BIT(1)));
-	input_event(input, EV_KEY, BTN_GRIPR, !!(b13 & BIT(2)));
-	input_event(input, EV_KEY, BTN_BASE, !!(b14 & BIT(2)));
+	steam_map_buttons(input, steam_deck_button_mappings, data);
+	steam_map_axes(input, steam_deck_axis_mappings, data);
 
 	input_sync(input);
 }
@@ -1690,12 +1740,7 @@ static void steam_do_deck_sensors_event(struct steam_device *steam,
 		return;
 
 	input_event(sensors, EV_MSC, MSC_TIMESTAMP, steam->sensor_timestamp_us);
-	input_report_abs(sensors, ABS_X, steam_le16(data + 24));
-	input_report_abs(sensors, ABS_Z, -steam_le16(data + 26));
-	input_report_abs(sensors, ABS_Y, steam_le16(data + 28));
-	input_report_abs(sensors, ABS_RX, steam_le16(data + 30));
-	input_report_abs(sensors, ABS_RZ, -steam_le16(data + 32));
-	input_report_abs(sensors, ABS_RY, steam_le16(data + 34));
+	steam_map_axes(sensors, steam_deck_imu_mappings, data);
 
 	input_sync(sensors);
 }
-- 
2.54.0


^ permalink raw reply related

* [PATCH v3 01/10] HID: steam: Update documentation
From: Vicki Pfau @ 2026-07-10  2:00 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, linux-input; +Cc: Vicki Pfau, Yousef Alhouseen
In-Reply-To: <20260710020048.2337655-1-vi@endrift.com>

Mark myself as the maintainer, as well as adding myself as an author.

It also makes some minor updates to comments, such as correcly calling the
left menu key view and retroactively renaming the original Steam Controller
as Steam Controller (2015), in preparation for support for the 2026 model.

Signed-off-by: Vicki Pfau <vi@endrift.com>
---
 MAINTAINERS             |  6 ++++++
 drivers/hid/hid-steam.c | 13 +++++++------
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4ecd282f8f52..2ed29e970023 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11500,6 +11500,12 @@ F:	drivers/hid/hid-sensor-*
 F:	drivers/iio/*/hid-*
 F:	include/linux/hid-sensor-*
 
+HID STEAM CONTROLLER
+M:	Vicki Pfau <vi@endrift.com>
+L:	linux-input@vger.kernel.org
+S:	Maintained
+F:	drivers/hid/hid-steam.c
+
 HID VRC-2 CAR CONTROLLER DRIVER
 M:	Marcus Folkesson <marcus.folkesson@gmail.com>
 L:	linux-input@vger.kernel.org
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index 197126d6e081..a854d6360a0e 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -48,6 +48,7 @@
 MODULE_DESCRIPTION("HID driver for Valve Steam Controller");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>");
+MODULE_AUTHOR("Vicki Pfau <vi@endrift.com>");
 
 static bool lizard_mode = true;
 
@@ -1413,9 +1414,9 @@ static inline s16 steam_le16(u8 *data)
  *  9.1  | BTN_DPAD_RIGHT | left-pad right
  *  9.2  | BTN_DPAD_LEFT  | left-pad left
  *  9.3  | BTN_DPAD_DOWN  | left-pad down
- *  9.4  | BTN_SELECT | menu left
+ *  9.4  | BTN_SELECT | view
  *  9.5  | BTN_MODE   | steam logo
- *  9.6  | BTN_START  | menu right
+ *  9.6  | BTN_START  | menu
  *  9.7  | BTN_GRIPL  | left back lever
  * 10.0  | BTN_GRIPR  | right back lever
  * 10.1  | --         | left-pad clicked
@@ -1541,9 +1542,9 @@ static void steam_do_input_event(struct steam_device *steam,
  *  9.1  | BTN_DPAD_RIGHT | left-pad right
  *  9.2  | BTN_DPAD_LEFT  | left-pad left
  *  9.3  | BTN_DPAD_DOWN  | left-pad down
- *  9.4  | BTN_SELECT | menu left
+ *  9.4  | BTN_SELECT | view
  *  9.5  | BTN_MODE   | steam logo
- *  9.6  | BTN_START  | menu right
+ *  9.6  | BTN_START  | menu
  *  9.7  | BTN_GRIPL2 | left bottom grip button
  *  10.0 | BTN_GRIPR2 | right bottom grip button
  *  10.1 | BTN_THUMB  | left pad pressed
@@ -1850,11 +1851,11 @@ MODULE_PARM_DESC(lizard_mode,
 	"Enable mouse and keyboard emulation (lizard mode) when the gamepad is not in use");
 
 static const struct hid_device_id steam_controllers[] = {
-	{ /* Wired Steam Controller */
+	{ /* Wired Steam Controller (2015) */
 	  HID_USB_DEVICE(USB_VENDOR_ID_VALVE,
 		USB_DEVICE_ID_STEAM_CONTROLLER)
 	},
-	{ /* Wireless Steam Controller */
+	{ /* Wireless Steam Controller (2015) */
 	  HID_USB_DEVICE(USB_VENDOR_ID_VALVE,
 		USB_DEVICE_ID_STEAM_CONTROLLER_WIRELESS),
 	  .driver_data = STEAM_QUIRK_WIRELESS
-- 
2.54.0


^ permalink raw reply related

* [PATCH v3 00/10] HID: steam: General cleanup and improvements
From: Vicki Pfau @ 2026-07-10  2:00 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, linux-input; +Cc: Vicki Pfau, Yousef Alhouseen

This is the first half of a patch series improving the hid-steam driver.

This series contains a few notable changes:
- As I've been maintaining it downstream in SteamOS as well as writing
  general improvements, I'm marking myself as the maintainer of the driver.
- Renames some stuff, notably marking the original Steam Controller as
  Steam Controller (2015) in preparation of adding support for the Steam
  Controller (2026), which will be in the second half of this series once
  it's ready for submission.
- Adds IMU support for the Steam Controller (2015).
- Some reliability improvements, especially surrounding edge cases
  regarding scheduled work during teardown.
- Fixes a short read issue reported by syzkaller.

Hopefully the second half of the series will be ready soon, but I am
waiting on more testing by SteamOS users before I submit it.

This is a minor interation on v2 that fixes a few issues that came up
during review of v2.

Vicki Pfau (10):
  HID: steam: Update documentation
  HID: steam: Refactor and clean up report parsing
  HID: steam: Rename some constants that got renamed upstream
  HID: steam: Add support for sensor events on the Steam Controller
    (2015)
  HID: steam: Coalesce rumble packets
  HID: steam: Fully unregister controller when hidraw is opened
  HID: steam: Rearrange teardown sequences
  HID: steam: Improve logging and other cleanup
  HID: steam: Reject short reads
  HID: steam: Retry send/recv reports if stale

 MAINTAINERS             |   6 +
 drivers/hid/hid-steam.c | 720 +++++++++++++++++++++++++++-------------
 2 files changed, 490 insertions(+), 236 deletions(-)

-- 
2.54.0


^ permalink raw reply

* Re: [PATCH v2 3/3] Input: ilitek_ts: ratelimit unexpected report logging
From: sashiko-bot @ 2026-07-09 18:40 UTC (permalink / raw)
  To: Kristian Mide; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260709182602.7308-4-kristian@mide.dk>

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:

New issues:
- [Medium] The patch fails to prevent dmesg spam because the caller logs an un-ratelimited error for any negative return value.
- [Low] Direct bit manipulation is used to set single device capabilities instead of the standard helper function.

Pre-existing issues:
- [High] Unbalanced disable_irq() in suspend and resume error paths leaves the device interrupt permanently disabled.
- [High] Multi-touch data parsing accesses incorrect buffer offsets for reports with more than 10 active touch points, parsing garbage data.
- [High] Returning IRQ_NONE for a serviced hardware interrupt can cause the kernel to permanently disable the IRQ line.
- [High] I2C transfer buffers are allocated on the stack, which can cause arbitrary physical memory corruption when DMA is used with vmapped stacks.
--

--- Patch [3]: [PATCH v2 3/3] Input: ilitek_ts: ratelimit unexpected report logging ---
commit bf03da99321dcdb2c6e97a5d9bbe75d687cccec8
Author: Kristian Mide <kristian@mide.dk>

Input: ilitek_ts: ratelimit unexpected report logging
    
Unexpected report IDs can repeat quickly when the controller
emits unknown packets.
    
Use dev_err_ratelimited() and include the first 16 bytes of the
raw packet to keep dmesg usable while preserving enough context
for debugging.

> diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c
> index 6146baa2b6062..e68bc052248ef 100644
> --- a/drivers/input/touchscreen/ilitek_ts_i2c.c
> +++ b/drivers/input/touchscreen/ilitek_ts_i2c.c
> @@ -238,7 +238,9 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
>  		return ilitek_process_pen_report(ts, buf);
>  
>  	if (buf[0] != ILITEK_TP_I2C_REPORT_ID) {
> -		dev_err(dev, "get touch info failed. Wrong id: 0x%02X\n", buf[0]);
> +		dev_err_ratelimited(dev,
> +				    "get touch info failed. Wrong id: 0x%02X raw[0:16]=%*ph\n",
> +				    buf[0], 16, buf);
>  		return -EINVAL;
>  	}

[Severity: Medium]
Does this actually prevent dmesg spam?  The caller ilitek_i2c_isr() observes
the -EINVAL return value and unconditionally logs an un-ratelimited error
for any negative return value:

drivers/input/touchscreen/ilitek_ts_i2c.c:ilitek_i2c_isr() {
    ...
    error = ilitek_process_and_report_v6(ts);
    if (error < 0) {
        dev_err(&ts->client->dev, "[%s] err:%d\n", __func__, error);
        return IRQ_NONE;
    }
    ...
}

[Severity: High]
This is a pre-existing issue, but returning IRQ_NONE from ilitek_i2c_isr()
after successfully executing I2C reads and clearing the hardware interrupt
can trigger the kernel's spurious interrupt detector.

If the hardware emits a stream of unexpected report IDs, will repeatedly
returning IRQ_NONE permanently disable the IRQ line?

[Severity: High]
This is a pre-existing issue, but does ilitek_process_and_report_v6()
incorrectly parse multi-touch data for reports with more than 10 active
touch points?

For 11+ points, the data is split into multiple 64-byte reads, but the loop
calculates a linear byte offset that completely disregards the 64-byte chunk
boundaries:

drivers/input/touchscreen/ilitek_ts_i2c.c:ilitek_process_and_report_v6() {
    ...
    for (i = 0; i < report_max_point; i++) {
        status = buf[i * packet_len + 1] & 0x40;
    ...
}

For the 11th point (index 10), this offset calculation (10 * 5 + 1 = 51)
reads from the padding of the first 64-byte chunk instead of advancing to
the next chunk.  Does this result in parsing garbage data?

[Severity: High]
This is a pre-existing issue, but does allocating I2C transfer buffers on the
stack cause arbitrary physical memory corruption when DMA is used?

drivers/input/touchscreen/ilitek_ts_i2c.c:ilitek_process_and_report_v6() {
    ...
    u8 buf[512];
    ...
    error = ilitek_i2c_write_and_read(ts, NULL, 0, 0, buf, 64);
    ...
}

If CONFIG_VMAP_STACK is enabled, the stack may not be physically contiguous.
Can a DMA transfer crossing a physical page boundary silently overwrite
unrelated physical memory?  (This also happens in ilitek_read_tp_info()
with a 256-byte stack buffer).

[Severity: Low]
Does ilitek_pen_input_dev_init() use direct bit manipulation to set single
device capabilities instead of the standard input_set_capability() helper?

drivers/input/touchscreen/ilitek_ts_i2c.c:ilitek_pen_input_dev_init() {
    ...
    __set_bit(INPUT_PROP_DIRECT, pen_input->propbit);
    __set_bit(EV_KEY, pen_input->evbit);
    __set_bit(EV_ABS, pen_input->evbit);
    ...
}

[Severity: High]
This is a pre-existing issue, but do the suspend and resume error paths leave
the device interrupt permanently disabled?

drivers/input/touchscreen/ilitek_ts_i2c.c:ilitek_suspend() {
    ...
    disable_irq(client->irq);

    if (!device_may_wakeup(dev)) {
        error = api_protocol_set_cmd(ts, SET_IC_SLEEP, NULL, NULL);
        if (error)
            return error;
    }
    ...
}

If api_protocol_set_cmd() fails, it bails out before enable_irq() can be
called to balance the disable_irq().  A similar issue exists in
ilitek_resume().  Does a failure during suspend/resume permanently kill
touchscreen functionality?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260709182602.7308-1-kristian@mide.dk?part=3

^ permalink raw reply

* Re: [PATCH v2 2/3] Input: ilitek_ts: handle short I2C transfers
From: sashiko-bot @ 2026-07-09 18:37 UTC (permalink / raw)
  To: Kristian Mide; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260709182602.7308-3-kristian@mide.dk>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing `enable_irq()` on error paths in suspend and resume functions.
- [High] Incorrect touch packet parsing offset across 64-byte chunks for points > 10.
--

--- Patch [2]: [PATCH v2 2/3] Input: ilitek_ts: handle short I2C transfers ---
commit fea6e8240af99ced183b54d3a3d2c69a63ac6791
Author: Kristian Mide <kristian@mide.dk>

Input: ilitek_ts: handle short I2C transfers

Check that i2c_transfer() returns the expected number of
messages in ilitek_i2c_write_and_read().

> diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c
> index 54e39721f2473..6146baa2b6062 100644
> --- a/drivers/input/touchscreen/ilitek_ts_i2c.c
> +++ b/drivers/input/touchscreen/ilitek_ts_i2c.c
> @@ -131,11 +131,15 @@ static int ilitek_i2c_write_and_read(struct ilitek_ts_data *ts,
>  		error = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
>  		if (error < 0)
>  			return error;
> +		if (error != ARRAY_SIZE(msgs))
> +			return -EIO;
>  	} else {
>  		if (write_len > 0) {
>  			error = i2c_transfer(client->adapter, msgs, 1);
>  			if (error < 0)
>  				return error;
> +			if (error != 1)
> +				return -EIO;
>  		}
>  		if (delay > 0)
>  			fsleep(delay * 1000);
> @@ -144,6 +148,8 @@ static int ilitek_i2c_write_and_read(struct ilitek_ts_data *ts,
>  			error = i2c_transfer(client->adapter, msgs + 1, 1);
>  			if (error < 0)
>  				return error;
> +			if (error != 1)
> +				return -EIO;
>  		}
>  	}

drivers/input/touchscreen/ilitek_ts_i2c.c:ilitek_suspend() {
    ...
    error = api_protocol_set_cmd(ts, SET_IC_SLEEP, NULL, NULL);
    if (error)
        return error;
    ...
}

[Severity: High]
This isn't a bug introduced by this patch, but does this error path return
early without re-enabling the IRQ that was disabled at the start of the
function?

If api_protocol_set_cmd() fails during system suspend or resume, the PM core
will abort the suspend process. Because enable_irq() is skipped, won't
ilitek_resume() not be called for this device, leaving the IRQ permanently
disabled and the device unresponsive?

drivers/input/touchscreen/ilitek_ts_i2c.c:ilitek_resume() {
    ...
    error = api_protocol_set_cmd(ts, SET_IC_WAKE, NULL, NULL);
    if (error)
        return error;
    ...
}

[Severity: High]
This is a pre-existing issue, but does this error path also return early
before the enable_irq() call is reached?

drivers/input/touchscreen/ilitek_ts_i2c.c:ilitek_process_and_report_v6() {
    ...
    status = buf[i * packet_len + 1] & 0x40;
    if (!status)
        continue;
        
    id = buf[i * packet_len + 1] & 0x3F;
    
    x = get_unaligned_le16(buf + i * packet_len + 2);
    y = get_unaligned_le16(buf + i * packet_len + 4);
    ...
}

[Severity: High]
This isn't a bug introduced by this patch, but does this purely linear
index calculation i * packet_len cause out-of-bounds offsets into padding
areas and conflict with metadata offsets for indices >= 10?

The driver reads touch points into buf in 64-byte chunks, each holding up
to 10 touch points, and advances the buffer pointer by 64 bytes for each
chunk.

Because each chunk only uses 50 bytes of data (leaving 14 bytes of padding),
won't the linear formula fail to account for the 64-byte chunk boundaries
instead of correctly tracking them?

For example, for the 11th point (i = 10), the driver should read from
buf[64], but it incorrectly reads from buf[50] (which is inside the first
chunk's padding). For i = 12, the offset buf[12 * 5 + 1] resolves to 61,
colliding exactly with REPORT_COUNT_ADDRESS, resulting in corrupted
coordinates and statuses for points > 10.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260709182602.7308-1-kristian@mide.dk?part=2

^ permalink raw reply

* Re: [PATCH v2 1/3] Input: ilitek_ts: add stylus input support
From: sashiko-bot @ 2026-07-09 18:36 UTC (permalink / raw)
  To: Kristian Mide; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260709182602.7308-2-kristian@mide.dk>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] If `api_protocol_set_cmd` fails during `ilitek_suspend`, the function returns an error without re-enabling the IRQ.
--

--- Patch [1]: [PATCH v2 1/3] Input: ilitek_ts: add stylus input support ---
commit 93b3664194ad6413b8e1020fb08120b8f1d2a174
Author: Kristian Mide <kristian@mide.dk>

Input: ilitek_ts: add stylus input support
    
Add a separate stylus input device for report ID 0x0c packets,
with pressure, hover, and side-button support.

> diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c
> index 3de0fbf8da386..54e39721f2473 100644
> --- a/drivers/input/touchscreen/ilitek_ts_i2c.c
> +++ b/drivers/input/touchscreen/ilitek_ts_i2c.c

[ ... ]

> @@ -600,6 +720,18 @@ static int ilitek_ts_i2c_probe(struct i2c_client *client)
>  	return 0;
>  }
>  
> +static void ilitek_ts_i2c_remove(struct i2c_client *client)
> +{
[ ... ]
> +}
> +
>  static int ilitek_suspend(struct device *dev)
>  {
>  	struct i2c_client *client = to_i2c_client(dev);

[Severity: High]
This isn't a bug introduced by this patch, but looking at ilitek_suspend():

drivers/input/touchscreen/ilitek_ts_i2c.c:ilitek_suspend() {
	...
	disable_irq(client->irq);

	if (!device_may_wakeup(dev)) {
		error = api_protocol_set_cmd(ts, SET_IC_SLEEP, NULL, NULL);
		if (error)
			return error;
	...
}

If api_protocol_set_cmd() fails, does returning the error directly leave
the IRQ permanently disabled?

If an error is returned during suspend, the PM core aborts the system suspend
and will not invoke the resume callback for this device. As a result,
enable_irq() would never be called, which could leave the touchscreen
unresponsive. Should this error path re-enable the IRQ before returning?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260709182602.7308-1-kristian@mide.dk?part=1

^ permalink raw reply

* [PATCH v2 3/3] Input: ilitek_ts: ratelimit unexpected report logging
From: Kristian Mide @ 2026-07-09 18:26 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: linux-input, linux-kernel, Kristian Mide
In-Reply-To: <20260709182602.7308-1-kristian@mide.dk>

Unexpected report IDs can repeat quickly when the controller
emits unknown packets.

Use dev_err_ratelimited() and include the first 16 bytes of the
raw packet to keep dmesg usable while preserving enough context
for debugging.
---
 drivers/input/touchscreen/ilitek_ts_i2c.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c
index 6146baa2b..e68bc0522 100644
--- a/drivers/input/touchscreen/ilitek_ts_i2c.c
+++ b/drivers/input/touchscreen/ilitek_ts_i2c.c
@@ -238,7 +238,9 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
 		return ilitek_process_pen_report(ts, buf);
 
 	if (buf[0] != ILITEK_TP_I2C_REPORT_ID) {
-		dev_err(dev, "get touch info failed. Wrong id: 0x%02X\n", buf[0]);
+		dev_err_ratelimited(dev,
+				    "get touch info failed. Wrong id: 0x%02X raw[0:16]=%*ph\n",
+				    buf[0], 16, buf);
 		return -EINVAL;
 	}
 
-- 
2.54.0


^ permalink raw reply related

* [PATCH v2 2/3] Input: ilitek_ts: handle short I2C transfers
From: Kristian Mide @ 2026-07-09 18:26 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: linux-input, linux-kernel, Kristian Mide
In-Reply-To: <20260709182602.7308-1-kristian@mide.dk>

Check that i2c_transfer() returns the expected number of
messages in ilitek_i2c_write_and_read().

Short transfers were previously treated as success, allowing
callers to continue with partially filled buffers. In the report
path that can expose uninitialized stack data through debugging
output and can also confuse packet parsing.
---
 drivers/input/touchscreen/ilitek_ts_i2c.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c
index 54e39721f..6146baa2b 100644
--- a/drivers/input/touchscreen/ilitek_ts_i2c.c
+++ b/drivers/input/touchscreen/ilitek_ts_i2c.c
@@ -131,11 +131,15 @@ static int ilitek_i2c_write_and_read(struct ilitek_ts_data *ts,
 		error = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
 		if (error < 0)
 			return error;
+		if (error != ARRAY_SIZE(msgs))
+			return -EIO;
 	} else {
 		if (write_len > 0) {
 			error = i2c_transfer(client->adapter, msgs, 1);
 			if (error < 0)
 				return error;
+			if (error != 1)
+				return -EIO;
 		}
 		if (delay > 0)
 			fsleep(delay * 1000);
@@ -144,6 +148,8 @@ static int ilitek_i2c_write_and_read(struct ilitek_ts_data *ts,
 			error = i2c_transfer(client->adapter, msgs + 1, 1);
 			if (error < 0)
 				return error;
+			if (error != 1)
+				return -EIO;
 		}
 	}
 
-- 
2.54.0


^ permalink raw reply related

* [PATCH v2 1/3] Input: ilitek_ts: add stylus input support
From: Kristian Mide @ 2026-07-09 18:26 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: linux-input, linux-kernel, Kristian Mide
In-Reply-To: <20260709182602.7308-1-kristian@mide.dk>

Add a separate stylus input device for report ID 0x0c packets,
with pressure, hover, and side-button support.

The pen device is created lazily on first pen report so
touchscreen-only hardware does not expose stylus capabilities up
front.

The packet format is reverse engineered from a tested CHUWI
Hi10 Max. Pressure is reported from buf[6..7] shifted right by
one, matching the observed 1024 pressure levels on the tested
device.

Pen coordinates are reported through touchscreen_report_pos()
so the same axis inversion and swapping properties used by the
touch path apply to the stylus as well.

The pen device lifetime is managed explicitly so the IRQ is
removed before the lazy pen input device is unregistered during
driver teardown.
---
 drivers/input/touchscreen/ilitek_ts_i2c.c | 139 +++++++++++++++++++++-
 1 file changed, 136 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c
index 3de0fbf8d..54e39721f 100644
--- a/drivers/input/touchscreen/ilitek_ts_i2c.c
+++ b/drivers/input/touchscreen/ilitek_ts_i2c.c
@@ -37,6 +37,18 @@
 #define ILITEK_TP_CMD_GET_IC_MODE			0xC0
 
 #define ILITEK_TP_I2C_REPORT_ID				0x48
+/* Reverse engineered stylus report on a tested CHUWI Hi10 Max device. */
+#define ILITEK_PEN_I2C_REPORT_ID			0x0C
+#define ILITEK_PEN_PRESSURE_MAX			1023
+#define ILITEK_PEN_DISTANCE_MAX			2
+/* Userspace expects tablet axis resolution; with INPUT_PROP_DIRECT this is */
+/* mostly descriptive and does not materially affect event coordinates. */
+#define ILITEK_PEN_RESOLUTION			68
+
+#define ILITEK_PEN_FLAG_TOUCH			0x01
+#define ILITEK_PEN_FLAG_STYLUS2			0x02
+#define ILITEK_PEN_FLAG_STYLUS			0x08
+#define ILITEK_PEN_FLAG_PROX			0x10
 
 #define REPORT_COUNT_ADDRESS				61
 #define ILITEK_SUPPORT_MAX_POINT			40
@@ -50,6 +62,7 @@ struct ilitek_ts_data {
 	struct i2c_client		*client;
 	struct gpio_desc		*reset_gpio;
 	struct input_dev		*input_dev;
+	struct input_dev		*pen_input_dev;
 	struct touchscreen_properties	prop;
 
 	const struct ilitek_protocol_map *ptl_cb_func;
@@ -89,6 +102,9 @@ enum ilitek_cmds {
 	MAX_CMD_CNT
 };
 
+static int ilitek_pen_input_dev_init(struct device *dev,
+				      struct ilitek_ts_data *ts);
+
 /* ILITEK I2C R/W APIs */
 static int ilitek_i2c_write_and_read(struct ilitek_ts_data *ts,
 				     u8 *cmd, int write_len, int delay,
@@ -146,6 +162,54 @@ static void ilitek_touch_down(struct ilitek_ts_data *ts, unsigned int id,
 	touchscreen_report_pos(input, &ts->prop, x, y, true);
 }
 
+/*
+ * buf[1] carries prox/touch/side-button state and buf[6..7] carries
+ * pressure. A right shift by one matches the observed 1024 pressure levels.
+ */
+static int ilitek_process_pen_report(struct ilitek_ts_data *ts, u8 *buf)
+{
+	struct device *dev = &ts->client->dev;
+	struct input_dev *input = ts->pen_input_dev;
+	unsigned int x, y, z, distance;
+	bool prox, touch, stylus, stylus2;
+	int error;
+
+	if (!input) {
+		error = ilitek_pen_input_dev_init(dev, ts);
+		if (error) {
+			dev_err_ratelimited(dev,
+					    "failed to register pen input device: %d\n",
+					    error);
+			return 0;
+		}
+		input = ts->pen_input_dev;
+	}
+
+	x = get_unaligned_le16(buf + 2);
+	y = get_unaligned_le16(buf + 4);
+	z = get_unaligned_le16(buf + 6) >> 1;
+	prox = !!(buf[1] & ILITEK_PEN_FLAG_PROX);
+	touch = !!(buf[1] & ILITEK_PEN_FLAG_TOUCH);
+	stylus = !!(buf[1] & ILITEK_PEN_FLAG_STYLUS);
+	stylus2 = !!(buf[1] & ILITEK_PEN_FLAG_STYLUS2);
+	distance = prox ? (touch ? 0 : 1) : ILITEK_PEN_DISTANCE_MAX;
+	if (!touch)
+		z = 0;
+	else if (z > ILITEK_PEN_PRESSURE_MAX)
+		z = ILITEK_PEN_PRESSURE_MAX;
+
+	input_report_key(input, BTN_TOOL_PEN, prox || touch);
+	input_report_key(input, BTN_TOUCH, touch);
+	input_report_key(input, BTN_STYLUS, stylus);
+	input_report_key(input, BTN_STYLUS2, stylus2);
+	touchscreen_report_pos(input, &ts->prop, x, y, false);
+	input_report_abs(input, ABS_PRESSURE, z);
+	input_report_abs(input, ABS_DISTANCE, distance);
+	input_sync(input);
+
+	return 0;
+}
+
 static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
 {
 	int error = 0;
@@ -164,6 +228,9 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
 		return error;
 	}
 
+	if (buf[0] == ILITEK_PEN_I2C_REPORT_ID)
+		return ilitek_process_pen_report(ts, buf);
+
 	if (buf[0] != ILITEK_TP_I2C_REPORT_ID) {
 		dev_err(dev, "get touch info failed. Wrong id: 0x%02X\n", buf[0]);
 		return -EINVAL;
@@ -459,6 +526,60 @@ static int ilitek_read_tp_info(struct ilitek_ts_data *ts, bool boot)
 	return 0;
 }
 
+static int ilitek_pen_input_dev_init(struct device *dev, struct ilitek_ts_data *ts)
+{
+	struct input_dev *pen_input;
+	int error;
+
+	if (ts->pen_input_dev)
+		return 0;
+
+	/* No explicit pen capability probe is known; create on first pen report. */
+
+	pen_input = input_allocate_device();
+	if (!pen_input)
+		return -ENOMEM;
+
+	ts->pen_input_dev = pen_input;
+	pen_input->dev.parent = dev;
+	pen_input->name = "ilitek_ts_pen";
+	pen_input->id.bustype = BUS_I2C;
+
+	__set_bit(INPUT_PROP_DIRECT, pen_input->propbit);
+	__set_bit(EV_KEY, pen_input->evbit);
+	__set_bit(EV_ABS, pen_input->evbit);
+	__set_bit(BTN_TOUCH, pen_input->keybit);
+	__set_bit(BTN_TOOL_PEN, pen_input->keybit);
+	__set_bit(BTN_STYLUS, pen_input->keybit);
+	__set_bit(BTN_STYLUS2, pen_input->keybit);
+
+	input_set_abs_params(pen_input, ABS_X,
+			     input_abs_get_min(ts->input_dev, ABS_MT_POSITION_X),
+			     input_abs_get_max(ts->input_dev, ABS_MT_POSITION_X),
+			     0, 0);
+	input_set_abs_params(pen_input, ABS_Y,
+			     input_abs_get_min(ts->input_dev, ABS_MT_POSITION_Y),
+			     input_abs_get_max(ts->input_dev, ABS_MT_POSITION_Y),
+			     0, 0);
+	input_set_abs_params(pen_input, ABS_PRESSURE, 0,
+			     ILITEK_PEN_PRESSURE_MAX, 0, 0);
+	input_set_abs_params(pen_input, ABS_DISTANCE, 0,
+			     ILITEK_PEN_DISTANCE_MAX, 0, 0);
+	input_abs_set_res(pen_input, ABS_X, ILITEK_PEN_RESOLUTION);
+	input_abs_set_res(pen_input, ABS_Y, ILITEK_PEN_RESOLUTION);
+
+	error = input_register_device(pen_input);
+	if (error)
+		goto err_free_pen_input;
+
+	return 0;
+
+err_free_pen_input:
+	ts->pen_input_dev = NULL;
+	input_free_device(pen_input);
+	return error;
+}
+
 static int ilitek_input_dev_init(struct device *dev, struct ilitek_ts_data *ts)
 {
 	int error;
@@ -589,9 +710,8 @@ static int ilitek_ts_i2c_probe(struct i2c_client *client)
 		return error;
 	}
 
-	error = devm_request_threaded_irq(dev, ts->client->irq,
-					  NULL, ilitek_i2c_isr, IRQF_ONESHOT,
-					  "ilitek_touch_irq", ts);
+	error = request_threaded_irq(ts->client->irq, NULL, ilitek_i2c_isr,
+				     IRQF_ONESHOT, "ilitek_touch_irq", ts);
 	if (error) {
 		dev_err(dev, "request threaded irq failed: %d\n", error);
 		return error;
@@ -600,6 +720,18 @@ static int ilitek_ts_i2c_probe(struct i2c_client *client)
 	return 0;
 }
 
+static void ilitek_ts_i2c_remove(struct i2c_client *client)
+{
+	struct ilitek_ts_data *ts = i2c_get_clientdata(client);
+
+	free_irq(client->irq, ts);
+
+	if (ts->pen_input_dev) {
+		input_unregister_device(ts->pen_input_dev);
+		ts->pen_input_dev = NULL;
+	}
+}
+
 static int ilitek_suspend(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
@@ -677,6 +809,7 @@ static struct i2c_driver ilitek_ts_i2c_driver = {
 		.acpi_match_table = ACPI_PTR(ilitekts_acpi_id),
 	},
 	.probe = ilitek_ts_i2c_probe,
+	.remove = ilitek_ts_i2c_remove,
 	.id_table = ilitek_ts_i2c_id,
 };
 module_i2c_driver(ilitek_ts_i2c_driver);
-- 
2.54.0


^ permalink raw reply related

* [PATCH v2 0/3] Input: ilitek_ts: add stylus support for 0x0c reports
From: Kristian Mide @ 2026-07-09 18:25 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: linux-input, linux-kernel, Kristian Mide
In-Reply-To: <20260626214248.5563-1-kristian@mide.dk>

Hi,

I bought a CHUWI Hi10 Max and was annoyed to find that the built-in
stylus was not usable with the upstream ilitek_ts driver.

This series adds support for the pen report format emitted by the
device, exposing the stylus as a separate input device with hover,
pressure, and side-button support. The pen device is created lazily on
first pen report so touchscreen-only hardware does not advertise stylus
capabilities up front.

The packet format was reverse engineered on this device. In particular,
report ID 0x0c appears to carry pen events, pressure comes from
buf[6..7] shifted right by one, and the side buttons map to two bits in
buf[1].

Changes in v2:
- manage the lazy pen device lifetime explicitly and tear down the IRQ
  before unregistering the pen device
- sync pen axis limits with the DT-adjusted touch axis limits
- reject short I2C transfers in ilitek_i2c_write_and_read()
- split the short-transfer fix from the ratelimited logging change

On the tested CHUWI Hi10 Max this makes the pen usable in GNOME/Krita,
including pressure and side buttons.

Thanks,
Kristian

Kristian Mide (3):
  Input: ilitek_ts: add stylus input support
  Input: ilitek_ts: handle short I2C transfers
  Input: ilitek_ts: ratelimit unexpected report logging

 drivers/input/touchscreen/ilitek_ts_i2c.c | 149 +++++++++++++++++++++-
 1 file changed, 145 insertions(+), 4 deletions(-)

-- 
2.54.0

^ permalink raw reply

* Re: [PATCH v2 01/11] dt-bindings: input: samsung,s3c6410-keypad: introduce compact binding
From: Conor Dooley @ 2026-07-09 17:56 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	Alim Akhtar, Russell King, Mark Brown, Linus Walleij,
	Charles Keepax, Sam Protsenko, Arnd Bergmann, Bartosz Golaszewski,
	Krzysztof Kozlowski, linux-input, devicetree, linux-kernel,
	linux-arm-kernel, linux-samsung-soc, patches
In-Reply-To: <20260708-samsung-kp-v2-1-3c6ed4c9b3b6@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 75 bytes --]

Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v2 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Sudeep Holla @ 2026-07-09 15:54 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Brian Masney, Bjorn Andersson, Cristian Marussi, Sudeep Holla,
	Nathan Chancellor, Nicolas Schier, Michael Turquette, arm-scmi,
	linux-arm-kernel, linux-kernel, linux-kbuild, Stephen Boyd,
	Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
	Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
	Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
	imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <158aa658-3109-4b7e-8213-1cc2cbd5aeb5@oss.qualcomm.com>

On Thu, Jul 09, 2026 at 04:49:18PM +0200, Hans de Goede wrote:
> Hi,
> 
> On 9-Jul-26 16:37, Sudeep Holla wrote:
> > On Thu, Jul 09, 2026 at 04:31:00PM +0200, Hans de Goede wrote:
> >> Hi,
> >>
> >> On 9-Jul-26 16:21, Sudeep Holla wrote:
> > [...]
> >>>
> >>> I need to recall why we moved from static list of devices to dynamic.
> >>> One reason I can think right now is the vendor protocols and their drivers
> >>> But in general it was an attempt to help multiple drivers bind to different
> >>> scmi_devices that have same protocol ID. E.g. the performance protocol
> >>> can be used by cpufreq and devfreq/performance genpd drivers.
> >>
> >> Note it is ok to have multiple drivers bind to the same modalias,
> >> depending on the reason why there are multiple drivers either one
> >> should detect that it is not compatible and exit probe() with -ENODEV
> >> or there should be some other mechanism to make sure only one driver
> >> loads.
> >>
> >> E.g. duplicate USB device-ids happen (they shouldn't but they do) and
> >> then the drivers typically figure out if they are talking to the device
> >> which they were written for, or the other device with the same USB-ids
> >> and then one of the 2 drivers exits with -ENODEV.
> >>
> > 
> > Understood. Sorry I tried to explain with examples assuming you may not
> > be aware of the details, but now reading your response, you have better
> > examples.
> > 
> >>>> I wonder if we can just move a small part of the drivers
> >>>> (some mapping table) into the bus code and then just have this work as it
> >>>> does on regular busses. I hope to be able to make some time to look into
> >>>> this soonish.
> >>>>
> >>>
> >>> I started with that few years ago and we then moved to this dynamic
> >>> device creation. But I agree if it is deviation from the norms(which I
> >>> wasn't aware of at the time), we can remove it.
> >>
> >> Looking at the issue this is causing for automatic module loading if we
> >> can get back to the bus enumeration code always creating a device without
> >> waiting for the driver kmod to load then that would be good IMHO.
> >>
> > 
> > Sure if it fixes the issue for you. Cristian can point out anything I
> > might have missed to consider as he is the one who reworked it and made
> > it dynamic device creation which at the time sounded nice option to
> > solve the issue. We weren't aware that it could cause such issues 🙁.
> 
> Note that before patch 1/2 of this series we did not have working
> module-autoloading for SCMI modules at all. With that said yes it would
> be nice to get this working.
> 
> Can you provide a patch for this to try ?
> 

Not sure what exactly are you asking, but I don't have anything w.r.t
the discussion handy to share. The codebase has moved a lot to revert
just the dynamic creation addition patch unfortunately.

-- 
Regards,
Sudeep

^ permalink raw reply

* Re: [RFC] Input: matrix_keypad: fix interrupt regression introduced by commit 01c84b03d80a
From: Siarhei Volkau @ 2026-07-09 15:51 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: Alexander Kochetkov, linux-input, Dmitry Torokhov, linux-kernel
In-Reply-To: <f8a6f9e3f5a7582c708669f22733add1a6b9ea8e.camel@crapouillou.net>

> Siarhei, do you remember the context of that patch?

Yes. My understanding is that at least some Ingenic GPIO controllers
don't report the current input level while the pin is configured for IRQs,
but instead expose the level latched at the moment the interrupt occurred.
That's what I was trying to work around.

> That was definitely working on the SoC I tested ...

You wouldn't notice this with the gpio-keys driver because its usage
pattern matches this behavior. For example, if the IRQ is configured
for the falling edge, then when the interrupt fires the level register will
read 0, which is exactly what gpio-keys expects.

I'm not sure whether this affects all Ingenic GPIO controllers,
but it should be easy to verify. For testing, you could temporarily
modify the driver as follows:

In the IRQ handler, before reconfiguring the IRQ for the opposite edge:
- read and print the GPIO level register/bit;
- wait for an arbitrary amount of time (long enough to release the
button between the two reads);
- read and print the GPIO level register/bit again.

If both reads return 0, even though the button has been released,
then the controller behaves like the JZ4755 and latches the GPIO
level at the time of the interrupt.
If the first read returns 0 and the second returns 1, then the controller
reports the live GPIO input level, as typical GPIO controllers do.

> I wonder if you were just experiencing bouncing?

I'm sure no, I remember that without that patch, I got the same readings
for all buttons in a row, no matter which column was active and as far as I
remember I tested it with arbitrary long col-scan-delay-us in range of
10-100 ms.

BR,
Siarhei

чт, 9 июл. 2026 г. в 13:25, Paul Cercueil <paul@crapouillou.net>:
>
> Hi,
>
> Siarhei, do you remember the context of that patch?
>
> The driver will read the pin level to emulate pins configured in "both
> edges" IRQ mode, and switch to "rising edge" if low, and "falling edge"
> if high. That was definitely working on the SoC I tested it with
> (probably JZ4770). I would be surprised if it did not work on the
> JZ4755.
>
> You mention in that commit message that you would get the pin level
> before the interrupt happened, I wonder if you were just experiencing
> bouncing?
>
> Anyway, I agree that this commit can be reverted.
>
> Le mercredi 08 juillet 2026 à 18:59 +0300, Siarhei Volkau a écrit :
> > Regarding JZ4755, I agree that the [1] patch can be reverted.
> > No device requiring this workaround has landed in the mainline.
> > qi,lb60 (Ben Nanonote) seems unaffected as it was there before
> > the patch was proposed.
> >
> > However, if there are genuinely two hardware operating modes:
> > - "GPIO input mode" while scanning
> > - "GPIO interrupt input mode" while idle
> > then the keypad driver should be aware of this distinction.
> >
> > I'd like to propose pinctrl state transitions as the mechanism for
> > switching
> > these modes, wherever it makes sense (Allwinner et al).
>
> I agree.
>
> >
> > CC Paul as the maintainer of Ingenic pinctrl driver.
> >
> > BR,
> > Siarhei
>
> Cheers,
> -Paul
>
> >
> >
> > ср, 8 июл. 2026 г. в 16:30, Alexander Kochetkov
> > <al.kochet@gmail.com>:
> > >
> > > Hi everyone,
> > >
> > > I found a commit [1] that breaks the matrix_keypad behavior on the
> > > Allwinner A64.
> > >
> > > I have a PINE A64-LTS board with a connected keypad polled by
> > > matrix_keypad.
> > > This commit caused interrupts to stop arriving at the matrix_keypad
> > > driver entirely.
> > >
> > > An explicit call to gpiod_direction_input() disables interrupt
> > > reception on all chips
> > > where the GPIO input mode and GPIO interrupt input mode are
> > > configured via
> > > the pinmux register. Interrupt reception is guaranteed to break on
> > > Allwinner
> > > (A64, H3, H6, etc.), Broadcom (BCM2835/2711), and some Rockchip
> > > SoCs. It
> > > does not break on NXP i.MX (i.MX6, i.MX8), STMicroelectronics
> > > (STM32MP1),
> > > TI Sitara (AM335x), or Intel/AMD.
> > >
> > > Furthermore, the assumption that enable_row_irqs() restores the
> > > interrupt mode is
> > > also specific to the Ingenic pinctrl. In the vast majority of
> > > drivers, enable_row_irqs() is
> > > supposed to simply set the interrupt enable mask without changing
> > > the pinmux.
> > >
> > > Commit [1] was introduced to work around a hardware limitation in
> > > Ingenic's JZ4755.
> > > This specific behavior is unique to Ingenic and a small number of
> > > specialized chips.
> > > The majority of SoCs (around 90%) allow reading a GPIO input that
> > > is currently configured
> > > as an interrupt source.
> > >
> > > In my opinion, the correct approach would be to revert this commit
> > > and fix the behavior of
> > > ingenic_gpio_get_value() inside pinctrl-ingenic.c instead. However,
> > > I do not own an Ingenic
> > > board, so I won't be able to test such a patch.
> > >
> > > Alternatively, I could introduce a DTS property like read-gpio-
> > > quirk in matrix_keypad to restore
> > > the original driver behavior by default, and add this property to
> > > qi_lb60.dts so as not to break
> > > the Ingenic platform.
> > >
> > > What do you think? What is the best way to proceed here?
> > >
> > > Best regards,
> > > Alexander Kochetkov
> > >
> > > [1] commit 01c84b03d80aab9f04c4e3e1f9085f4202ff7c29 ("Input:
> > > matrix_keypad - force switch rows to input mode")

^ permalink raw reply

* Re: [PATCH v2 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Cristian Marussi @ 2026-07-09 15:49 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Hans de Goede, Brian Masney, Bjorn Andersson, Cristian Marussi,
	Nathan Chancellor, Nicolas Schier, Michael Turquette, arm-scmi,
	linux-arm-kernel, linux-kernel, linux-kbuild, Stephen Boyd,
	Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
	Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
	Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
	imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <20260709-exuberant-narwhal-of-correction-7f4650@sudeepholla>

On Thu, Jul 09, 2026 at 03:37:33PM +0100, Sudeep Holla wrote:
> On Thu, Jul 09, 2026 at 04:31:00PM +0200, Hans de Goede wrote:
> > Hi,
> > 
> > On 9-Jul-26 16:21, Sudeep Holla wrote:
> [...]
> > > 
> > > I need to recall why we moved from static list of devices to dynamic.
> > > One reason I can think right now is the vendor protocols and their drivers
> > > But in general it was an attempt to help multiple drivers bind to different
> > > scmi_devices that have same protocol ID. E.g. the performance protocol
> > > can be used by cpufreq and devfreq/performance genpd drivers.
> > 
> > Note it is ok to have multiple drivers bind to the same modalias,
> > depending on the reason why there are multiple drivers either one
> > should detect that it is not compatible and exit probe() with -ENODEV
> > or there should be some other mechanism to make sure only one driver
> > loads.
> > 
> > E.g. duplicate USB device-ids happen (they shouldn't but they do) and
> > then the drivers typically figure out if they are talking to the device
> > which they were written for, or the other device with the same USB-ids
> > and then one of the 2 drivers exits with -ENODEV.
> > 
> 
> Understood. Sorry I tried to explain with examples assuming you may not
> be aware of the details, but now reading your response, you have better
> examples.
> 
> > >> I wonder if we can just move a small part of the drivers
> > >> (some mapping table) into the bus code and then just have this work as it
> > >> does on regular busses. I hope to be able to make some time to look into
> > >> this soonish.
> > >>
> > > 
> > > I started with that few years ago and we then moved to this dynamic
> > > device creation. But I agree if it is deviation from the norms(which I
> > > wasn't aware of at the time), we can remove it.
> > 
> > Looking at the issue this is causing for automatic module loading if we
> > can get back to the bus enumeration code always creating a device without
> > waiting for the driver kmod to load then that would be good IMHO.
> > 
> 
> Sure if it fixes the issue for you. Cristian can point out anything I
> might have missed to consider as he is the one who reworked it and made
> it dynamic device creation which at the time sounded nice option to
> solve the issue. We weren't aware that it could cause such issues 🙁.
> 

The reason for the awkward mechanism of dynamic device creation AFAICR
was an explicit request by Qualcomm (via its Linaro landing team at
that time) for the generic vendor module suppport that I was adding to
be fully self-contained: so that you can write your own protocol and
add the DT node and that's it, without the need to patch some centrally
maintained table in the core SCMI stack to add your new vendor protocol.

Not saying that it was necesarily a good idea to allow that, but that
was the origin of this....as far as I can remember....together with the
fact that the internal interfaces were reworked to be absolutely the
same for standard protocols and vendor protocols...

I thought that the current situation was that auto-loading was working
for vendor protocols (this autoload issue appeared at first for vendors
protocols one year ago) then I had made this hacky attempt to make it
work for standard protocols by forcibly emitting a uevent for all known
standard protos:

https://lore.kernel.org/arm-scmi/20250203100154.140877-2-cristian.marussi@arm.com/


...but that was clearly not the proper way..and all the rework was
dropped...

Thanks,
Cristian

^ permalink raw reply

* Re: [PATCH v2 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Hans de Goede @ 2026-07-09 14:49 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Brian Masney, Bjorn Andersson, Cristian Marussi,
	Nathan Chancellor, Nicolas Schier, Michael Turquette, arm-scmi,
	linux-arm-kernel, linux-kernel, linux-kbuild, Stephen Boyd,
	Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
	Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
	Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
	imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <20260709-exuberant-narwhal-of-correction-7f4650@sudeepholla>

Hi,

On 9-Jul-26 16:37, Sudeep Holla wrote:
> On Thu, Jul 09, 2026 at 04:31:00PM +0200, Hans de Goede wrote:
>> Hi,
>>
>> On 9-Jul-26 16:21, Sudeep Holla wrote:
> [...]
>>>
>>> I need to recall why we moved from static list of devices to dynamic.
>>> One reason I can think right now is the vendor protocols and their drivers
>>> But in general it was an attempt to help multiple drivers bind to different
>>> scmi_devices that have same protocol ID. E.g. the performance protocol
>>> can be used by cpufreq and devfreq/performance genpd drivers.
>>
>> Note it is ok to have multiple drivers bind to the same modalias,
>> depending on the reason why there are multiple drivers either one
>> should detect that it is not compatible and exit probe() with -ENODEV
>> or there should be some other mechanism to make sure only one driver
>> loads.
>>
>> E.g. duplicate USB device-ids happen (they shouldn't but they do) and
>> then the drivers typically figure out if they are talking to the device
>> which they were written for, or the other device with the same USB-ids
>> and then one of the 2 drivers exits with -ENODEV.
>>
> 
> Understood. Sorry I tried to explain with examples assuming you may not
> be aware of the details, but now reading your response, you have better
> examples.
> 
>>>> I wonder if we can just move a small part of the drivers
>>>> (some mapping table) into the bus code and then just have this work as it
>>>> does on regular busses. I hope to be able to make some time to look into
>>>> this soonish.
>>>>
>>>
>>> I started with that few years ago and we then moved to this dynamic
>>> device creation. But I agree if it is deviation from the norms(which I
>>> wasn't aware of at the time), we can remove it.
>>
>> Looking at the issue this is causing for automatic module loading if we
>> can get back to the bus enumeration code always creating a device without
>> waiting for the driver kmod to load then that would be good IMHO.
>>
> 
> Sure if it fixes the issue for you. Cristian can point out anything I
> might have missed to consider as he is the one who reworked it and made
> it dynamic device creation which at the time sounded nice option to
> solve the issue. We weren't aware that it could cause such issues 🙁.

Note that before patch 1/2 of this series we did not have working
module-autoloading for SCMI modules at all. With that said yes it would
be nice to get this working.

Can you provide a patch for this to try ?

Regards,

Hans



^ permalink raw reply

* Re: [PATCH v2 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Sudeep Holla @ 2026-07-09 14:37 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Brian Masney, Bjorn Andersson, Sudeep Holla, Cristian Marussi,
	Nathan Chancellor, Nicolas Schier, Michael Turquette, arm-scmi,
	linux-arm-kernel, linux-kernel, linux-kbuild, Stephen Boyd,
	Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
	Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
	Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
	imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <5fb236b7-7b99-40fb-b80b-fa7e1dfccd70@oss.qualcomm.com>

On Thu, Jul 09, 2026 at 04:31:00PM +0200, Hans de Goede wrote:
> Hi,
> 
> On 9-Jul-26 16:21, Sudeep Holla wrote:
[...]
> > 
> > I need to recall why we moved from static list of devices to dynamic.
> > One reason I can think right now is the vendor protocols and their drivers
> > But in general it was an attempt to help multiple drivers bind to different
> > scmi_devices that have same protocol ID. E.g. the performance protocol
> > can be used by cpufreq and devfreq/performance genpd drivers.
> 
> Note it is ok to have multiple drivers bind to the same modalias,
> depending on the reason why there are multiple drivers either one
> should detect that it is not compatible and exit probe() with -ENODEV
> or there should be some other mechanism to make sure only one driver
> loads.
> 
> E.g. duplicate USB device-ids happen (they shouldn't but they do) and
> then the drivers typically figure out if they are talking to the device
> which they were written for, or the other device with the same USB-ids
> and then one of the 2 drivers exits with -ENODEV.
> 

Understood. Sorry I tried to explain with examples assuming you may not
be aware of the details, but now reading your response, you have better
examples.

> >> I wonder if we can just move a small part of the drivers
> >> (some mapping table) into the bus code and then just have this work as it
> >> does on regular busses. I hope to be able to make some time to look into
> >> this soonish.
> >>
> > 
> > I started with that few years ago and we then moved to this dynamic
> > device creation. But I agree if it is deviation from the norms(which I
> > wasn't aware of at the time), we can remove it.
> 
> Looking at the issue this is causing for automatic module loading if we
> can get back to the bus enumeration code always creating a device without
> waiting for the driver kmod to load then that would be good IMHO.
> 

Sure if it fixes the issue for you. Cristian can point out anything I
might have missed to consider as he is the one who reworked it and made
it dynamic device creation which at the time sounded nice option to
solve the issue. We weren't aware that it could cause such issues 🙁.

-- 
Regards,
Sudeep

^ permalink raw reply

* Re: [PATCH v2 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Hans de Goede @ 2026-07-09 14:31 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Brian Masney, Bjorn Andersson, Cristian Marussi,
	Nathan Chancellor, Nicolas Schier, Michael Turquette, arm-scmi,
	linux-arm-kernel, linux-kernel, linux-kbuild, Stephen Boyd,
	Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
	Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
	Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
	imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <20260709-exuberant-galago-of-spirit-1c908f@sudeepholla>

Hi,

On 9-Jul-26 16:21, Sudeep Holla wrote:
> On Thu, Jul 09, 2026 at 04:07:17PM +0200, Hans de Goede wrote:
>> Hi Brian,
>>
>> On 9-Jul-26 15:28, Brian Masney wrote:
>>> Hi Hans,
>>>
>>> On Thu, Jul 09, 2026 at 03:22:29PM +0200, Hans de Goede wrote:
>>>> On 9-Jul-26 12:10, Sudeep Holla wrote:
>>>>> On Thu, Jun 18, 2026 at 10:31:12PM +0200, Hans de Goede wrote:
>>>>>> On 18-Jun-26 17:56, Bjorn Andersson wrote:
>>>>>>> SCMI drivers such as the Arm SCMI CPUfreq driver are allowed to built as
>>>>>>> modules, but they are then not automatically loaded. Rework the SCMI
>>>>>>> device table alias support to make modpost consume the information from
>>>>>>> MODULE_DEVICE_TABLE(scmi, ...) and allow drivers to be loaded based on
>>>>>>> this information, if known. Also add a protocol-based alias to also
>>>>>>> trigger driver loading when only the SCMI protocol id is known.
>>>>>>>
>>>>>>> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
>>>>>>
>>>>>> So I just gave this a test spin and unfortunately it does not work.
>>>>>>
>>>>>> The problem with Fedora's kernel-config / setup is that the
>>>>>> request_module() from patch 2/2 runs from the initramfs, but
>>>>>> the scmi_cpufreq module is only available in the rootfs.
>>>>>>
>>>>>> It does work if I explictly add the scmi_cpufreq module to
>>>>>> the initramfs, then it does get autoloaded.
>>>>>>
>>>>>> We really need some place to put a uevent sysfs attr which then
>>>>>> gets replayed when udev is restarted from the rootfs and then
>>>>>> re-reads all the uevent files as part of its coldplug
>>>>>> enumeration.
>>>>>>
>>>>>
>>>>> I don't have much knowledge on uevent to provide any suggestions/help.
>>>>> But isn't this a generic requirement ? I mean you could have modules
>>>>> install on the rootfs and not all of them are packed in initramfs ?
>>>>> Just wondering if that works for other modules, we can examine how
>>>>> do they work and what are we missing ?
>>>>
>>>> scmi is special because the actual devices under /sys/bus/scmi/devices
>>>> only get created when the module with the driver is loaded because
>>>> of some funtion/id mapping requiring info from the driver.
>>>>
>>>> Patch 2/2 tries to work around this by loading all scmi drivers matching
>>>> the scmi protocol which is known at bus enumeration time, but this only
>>>> works if the actual scmi driver is in the initramfs because this done
>>>> through directly calling modprobe() from the kernel which does not
>>>> get "replayed" when switching to the real rootfs.
>>>
>>> Should the SCMI drivers be added to the dracut module here?
>>>
>>> https://github.com/dracut-ng/dracut/blob/main/modules.d/70kernel-modules/module-setup.sh#L73
>>>
>>> A few years ago we had to add the interconnect drivers to the list for
>>> Fedora.
>>
>> That would be one solution. I first want to understand the problem better
>> though. The scmi bus not creating the devices until the kmod with the driver
>> has loaded is weird.
> 
> I need to recall why we moved from static list of devices to dynamic.
> One reason I can think right now is the vendor protocols and their drivers
> But in general it was an attempt to help multiple drivers bind to different
> scmi_devices that have same protocol ID. E.g. the performance protocol
> can be used by cpufreq and devfreq/performance genpd drivers.

Note it is ok to have multiple drivers bind to the same modalias,
depending on the reason why there are multiple drivers either one
should detect that it is not compatible and exit probe() with -ENODEV
or there should be some other mechanism to make sure only one driver
loads.

E.g. duplicate USB device-ids happen (they shouldn't but they do) and
then the drivers typically figure out if they are talking to the device
which they were written for, or the other device with the same USB-ids
and then one of the 2 drivers exits with -ENODEV.

>> I wonder if we can just move a small part of the drivers
>> (some mapping table) into the bus code and then just have this work as it
>> does on regular busses. I hope to be able to make some time to look into
>> this soonish.
>>
> 
> I started with that few years ago and we then moved to this dynamic
> device creation. But I agree if it is deviation from the norms(which I
> wasn't aware of at the time), we can remove it.

Looking at the issue this is causing for automatic module loading if we
can get back to the bus enumeration code always creating a device without
waiting for the driver kmod to load then that would be good IMHO.

Regards,

Hans



^ permalink raw reply

* Re: [PATCH v2 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Sudeep Holla @ 2026-07-09 14:21 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Brian Masney, Bjorn Andersson, Sudeep Holla, Cristian Marussi,
	Nathan Chancellor, Nicolas Schier, Michael Turquette, arm-scmi,
	linux-arm-kernel, linux-kernel, linux-kbuild, Stephen Boyd,
	Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
	Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
	Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
	imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <f05860be-dd75-49f8-b27a-bff7b554e71b@oss.qualcomm.com>

On Thu, Jul 09, 2026 at 04:07:17PM +0200, Hans de Goede wrote:
> Hi Brian,
> 
> On 9-Jul-26 15:28, Brian Masney wrote:
> > Hi Hans,
> > 
> > On Thu, Jul 09, 2026 at 03:22:29PM +0200, Hans de Goede wrote:
> >> On 9-Jul-26 12:10, Sudeep Holla wrote:
> >>> On Thu, Jun 18, 2026 at 10:31:12PM +0200, Hans de Goede wrote:
> >>>> On 18-Jun-26 17:56, Bjorn Andersson wrote:
> >>>>> SCMI drivers such as the Arm SCMI CPUfreq driver are allowed to built as
> >>>>> modules, but they are then not automatically loaded. Rework the SCMI
> >>>>> device table alias support to make modpost consume the information from
> >>>>> MODULE_DEVICE_TABLE(scmi, ...) and allow drivers to be loaded based on
> >>>>> this information, if known. Also add a protocol-based alias to also
> >>>>> trigger driver loading when only the SCMI protocol id is known.
> >>>>>
> >>>>> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
> >>>>
> >>>> So I just gave this a test spin and unfortunately it does not work.
> >>>>
> >>>> The problem with Fedora's kernel-config / setup is that the
> >>>> request_module() from patch 2/2 runs from the initramfs, but
> >>>> the scmi_cpufreq module is only available in the rootfs.
> >>>>
> >>>> It does work if I explictly add the scmi_cpufreq module to
> >>>> the initramfs, then it does get autoloaded.
> >>>>
> >>>> We really need some place to put a uevent sysfs attr which then
> >>>> gets replayed when udev is restarted from the rootfs and then
> >>>> re-reads all the uevent files as part of its coldplug
> >>>> enumeration.
> >>>>
> >>>
> >>> I don't have much knowledge on uevent to provide any suggestions/help.
> >>> But isn't this a generic requirement ? I mean you could have modules
> >>> install on the rootfs and not all of them are packed in initramfs ?
> >>> Just wondering if that works for other modules, we can examine how
> >>> do they work and what are we missing ?
> >>
> >> scmi is special because the actual devices under /sys/bus/scmi/devices
> >> only get created when the module with the driver is loaded because
> >> of some funtion/id mapping requiring info from the driver.
> >>
> >> Patch 2/2 tries to work around this by loading all scmi drivers matching
> >> the scmi protocol which is known at bus enumeration time, but this only
> >> works if the actual scmi driver is in the initramfs because this done
> >> through directly calling modprobe() from the kernel which does not
> >> get "replayed" when switching to the real rootfs.
> > 
> > Should the SCMI drivers be added to the dracut module here?
> > 
> > https://github.com/dracut-ng/dracut/blob/main/modules.d/70kernel-modules/module-setup.sh#L73
> > 
> > A few years ago we had to add the interconnect drivers to the list for
> > Fedora.
> 
> That would be one solution. I first want to understand the problem better
> though. The scmi bus not creating the devices until the kmod with the driver
> has loaded is weird.

I need to recall why we moved from static list of devices to dynamic.
One reason I can think right now is the vendor protocols and their drivers
But in general it was an attempt to help multiple drivers bind to different
scmi_devices that have same protocol ID. E.g. the performance protocol
can be used by cpufreq and devfreq/performance genpd drivers.

> I wonder if we can just move a small part of the drivers
> (some mapping table) into the bus code and then just have this work as it
> does on regular busses. I hope to be able to make some time to look into
> this soonish.
> 

I started with that few years ago and we then moved to this dynamic
device creation. But I agree if it is deviation from the norms(which I
wasn't aware of at the time), we can remove it.

-- 
Regards,
Sudeep

^ permalink raw reply

* [PATCH] HID: sony: add missing __packed to struct with static_assert()
From: Rosalie Wanders @ 2026-07-09 14:12 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Rosalie Wanders
  Cc: kernel test robot, linux-input, linux-kernel

Fixes: 4b9c410e7d6d ("HID: sony: fix style issues")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202607091026.R9Pxd3PG-lkp@intel.com/
Signed-off-by: Rosalie Wanders <rosalie@mailbox.org>
---
 drivers/hid/hid-sony.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 253fff4066eb..b7392467191f 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -505,7 +505,7 @@ struct motion_output_report_02 {
 	u8 r, g, b;
 	u8 zero2;
 	u8 rumble;
-};
+} __packed;
 static_assert(sizeof(struct motion_output_report_02) == 7);
 
 #define SIXAXIS_REPORT_0xF2_SIZE 17
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH v2 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Hans de Goede @ 2026-07-09 14:07 UTC (permalink / raw)
  To: Brian Masney
  Cc: Sudeep Holla, Bjorn Andersson, Cristian Marussi,
	Nathan Chancellor, Nicolas Schier, Michael Turquette, arm-scmi,
	linux-arm-kernel, linux-kernel, linux-kbuild, Stephen Boyd,
	Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
	Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
	Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
	imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <ak-h8oPcL69fCUg2@redhat.com>

Hi Brian,

On 9-Jul-26 15:28, Brian Masney wrote:
> Hi Hans,
> 
> On Thu, Jul 09, 2026 at 03:22:29PM +0200, Hans de Goede wrote:
>> On 9-Jul-26 12:10, Sudeep Holla wrote:
>>> On Thu, Jun 18, 2026 at 10:31:12PM +0200, Hans de Goede wrote:
>>>> On 18-Jun-26 17:56, Bjorn Andersson wrote:
>>>>> SCMI drivers such as the Arm SCMI CPUfreq driver are allowed to built as
>>>>> modules, but they are then not automatically loaded. Rework the SCMI
>>>>> device table alias support to make modpost consume the information from
>>>>> MODULE_DEVICE_TABLE(scmi, ...) and allow drivers to be loaded based on
>>>>> this information, if known. Also add a protocol-based alias to also
>>>>> trigger driver loading when only the SCMI protocol id is known.
>>>>>
>>>>> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
>>>>
>>>> So I just gave this a test spin and unfortunately it does not work.
>>>>
>>>> The problem with Fedora's kernel-config / setup is that the
>>>> request_module() from patch 2/2 runs from the initramfs, but
>>>> the scmi_cpufreq module is only available in the rootfs.
>>>>
>>>> It does work if I explictly add the scmi_cpufreq module to
>>>> the initramfs, then it does get autoloaded.
>>>>
>>>> We really need some place to put a uevent sysfs attr which then
>>>> gets replayed when udev is restarted from the rootfs and then
>>>> re-reads all the uevent files as part of its coldplug
>>>> enumeration.
>>>>
>>>
>>> I don't have much knowledge on uevent to provide any suggestions/help.
>>> But isn't this a generic requirement ? I mean you could have modules
>>> install on the rootfs and not all of them are packed in initramfs ?
>>> Just wondering if that works for other modules, we can examine how
>>> do they work and what are we missing ?
>>
>> scmi is special because the actual devices under /sys/bus/scmi/devices
>> only get created when the module with the driver is loaded because
>> of some funtion/id mapping requiring info from the driver.
>>
>> Patch 2/2 tries to work around this by loading all scmi drivers matching
>> the scmi protocol which is known at bus enumeration time, but this only
>> works if the actual scmi driver is in the initramfs because this done
>> through directly calling modprobe() from the kernel which does not
>> get "replayed" when switching to the real rootfs.
> 
> Should the SCMI drivers be added to the dracut module here?
> 
> https://github.com/dracut-ng/dracut/blob/main/modules.d/70kernel-modules/module-setup.sh#L73
> 
> A few years ago we had to add the interconnect drivers to the list for
> Fedora.

That would be one solution. I first want to understand the problem better
though. The scmi bus not creating the devices until the kmod with the driver
has loaded is weird. I wonder if we can just move a small part of the drivers
(some mapping table) into the bus code and then just have this work as it
does on regular busses. I hope to be able to make some time to look into
this soonish.

Regards,

Hans


^ permalink raw reply

* Re: [PATCH v2 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Brian Masney @ 2026-07-09 13:28 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sudeep Holla, Bjorn Andersson, Cristian Marussi,
	Nathan Chancellor, Nicolas Schier, Michael Turquette, arm-scmi,
	linux-arm-kernel, linux-kernel, linux-kbuild, Stephen Boyd,
	Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
	Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
	Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
	imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <dae4deba-7e5f-434e-80ae-89033bdeb793@oss.qualcomm.com>

Hi Hans,

On Thu, Jul 09, 2026 at 03:22:29PM +0200, Hans de Goede wrote:
> On 9-Jul-26 12:10, Sudeep Holla wrote:
> > On Thu, Jun 18, 2026 at 10:31:12PM +0200, Hans de Goede wrote:
> >> On 18-Jun-26 17:56, Bjorn Andersson wrote:
> >>> SCMI drivers such as the Arm SCMI CPUfreq driver are allowed to built as
> >>> modules, but they are then not automatically loaded. Rework the SCMI
> >>> device table alias support to make modpost consume the information from
> >>> MODULE_DEVICE_TABLE(scmi, ...) and allow drivers to be loaded based on
> >>> this information, if known. Also add a protocol-based alias to also
> >>> trigger driver loading when only the SCMI protocol id is known.
> >>>
> >>> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
> >>
> >> So I just gave this a test spin and unfortunately it does not work.
> >>
> >> The problem with Fedora's kernel-config / setup is that the
> >> request_module() from patch 2/2 runs from the initramfs, but
> >> the scmi_cpufreq module is only available in the rootfs.
> >>
> >> It does work if I explictly add the scmi_cpufreq module to
> >> the initramfs, then it does get autoloaded.
> >>
> >> We really need some place to put a uevent sysfs attr which then
> >> gets replayed when udev is restarted from the rootfs and then
> >> re-reads all the uevent files as part of its coldplug
> >> enumeration.
> >>
> > 
> > I don't have much knowledge on uevent to provide any suggestions/help.
> > But isn't this a generic requirement ? I mean you could have modules
> > install on the rootfs and not all of them are packed in initramfs ?
> > Just wondering if that works for other modules, we can examine how
> > do they work and what are we missing ?
> 
> scmi is special because the actual devices under /sys/bus/scmi/devices
> only get created when the module with the driver is loaded because
> of some funtion/id mapping requiring info from the driver.
> 
> Patch 2/2 tries to work around this by loading all scmi drivers matching
> the scmi protocol which is known at bus enumeration time, but this only
> works if the actual scmi driver is in the initramfs because this done
> through directly calling modprobe() from the kernel which does not
> get "replayed" when switching to the real rootfs.

Should the SCMI drivers be added to the dracut module here?

https://github.com/dracut-ng/dracut/blob/main/modules.d/70kernel-modules/module-setup.sh#L73

A few years ago we had to add the interconnect drivers to the list for
Fedora.

Brian


^ permalink raw reply

* Re: [PATCH v2 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Hans de Goede @ 2026-07-09 13:22 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Bjorn Andersson, Cristian Marussi, Nathan Chancellor,
	Nicolas Schier, Michael Turquette, arm-scmi, linux-arm-kernel,
	linux-kernel, linux-kbuild, Stephen Boyd, Brian Masney,
	Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
	Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
	Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
	imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <20260709-spicy-fiery-squid-6eec1d@sudeepholla>

Hi,

On 9-Jul-26 12:10, Sudeep Holla wrote:
> On Thu, Jun 18, 2026 at 10:31:12PM +0200, Hans de Goede wrote:
>> Hi,
>>
>> On 18-Jun-26 17:56, Bjorn Andersson wrote:
>>> SCMI drivers such as the Arm SCMI CPUfreq driver are allowed to built as
>>> modules, but they are then not automatically loaded. Rework the SCMI
>>> device table alias support to make modpost consume the information from
>>> MODULE_DEVICE_TABLE(scmi, ...) and allow drivers to be loaded based on
>>> this information, if known. Also add a protocol-based alias to also
>>> trigger driver loading when only the SCMI protocol id is known.
>>>
>>> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
>>
>> So I just gave this a test spin and unfortunately it does not work.
>>
>> The problem with Fedora's kernel-config / setup is that the
>> request_module() from patch 2/2 runs from the initramfs, but
>> the scmi_cpufreq module is only available in the rootfs.
>>
>> It does work if I explictly add the scmi_cpufreq module to
>> the initramfs, then it does get autoloaded.
>>
>> We really need some place to put a uevent sysfs attr which then
>> gets replayed when udev is restarted from the rootfs and then
>> re-reads all the uevent files as part of its coldplug
>> enumeration.
>>
> 
> I don't have much knowledge on uevent to provide any suggestions/help.
> But isn't this a generic requirement ? I mean you could have modules
> install on the rootfs and not all of them are packed in initramfs ?
> Just wondering if that works for other modules, we can examine how
> do they work and what are we missing ?

scmi is special because the actual devices under /sys/bus/scmi/devices
only get created when the module with the driver is loaded because
of some funtion/id mapping requiring info from the driver.

Patch 2/2 tries to work around this by loading all scmi drivers matching
the scmi protocol which is known at bus enumeration time, but this only
works if the actual scmi driver is in the initramfs because this done
through directly calling modprobe() from the kernel which does not
get "replayed" when switching to the real rootfs.

And no /sys/bus/scmi/devices/xxx device means no
/sys/bus/scmi/devices/xxx/modalias nor /sys/bus/scmi/devices/xxx/uevent
which udev uses for coldplug (hotplug event replay) when switching to
the real root.

The cleanest way to fix this from a how things are supposed to work
according to the generic kernel device-model design is to get rid of
the creation of the devices being delayed. Which may mean moving some
static mapping tables from the driver into the scmi core. I'm not
familiar enough with the scmi bus code to be sure.

Regards,

Hans


> 



^ permalink raw reply

* Re: [PATCH v9 0/9] Add support for MT6392 PMIC
From: AngeloGioacchino Del Regno @ 2026-07-09 12:00 UTC (permalink / raw)
  To: Luca Leonardo Scorcia, linux-mediatek
  Cc: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Sen Chu, Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
	Liam Girdwood, Mark Brown, Linus Walleij, Louis-Alexis Eyraud,
	Val Packett, Julien Massot, Fabien Parent, Akari Tsuyukusa,
	Chen Zhong, linux-input, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, linux-gpio
In-Reply-To: <20260621081634.467858-1-l.scorcia@gmail.com>

On 6/21/26 10:13, Luca Leonardo Scorcia wrote:
> The MediaTek MT6392 PMIC is usually found on devices powered by
> the MT8516/MT8167 SoC and is yet another MT6323/MT6397 variant.
> 
> This series is mostly based around patches submitted a couple
> years ago by Fabien Parent and not merged and from Val Packett's
> submission from Jan 2025 that included extra cleanups, fixes, and a
> new dtsi file similar to ones that exist for other PMICs. Some
> comments weren't addressed and the series was ultimately not merged.
> 
> These patches enable four functions: keys, regulator, pinctrl and RTC.
> Mono speaker amp will follow later as I need to work further on the
> audio codec.
> 
> I added a handful of device tree improvements to fix some dtbs_check
> errors, added support for the pinctrl device and addressed the comments
> from last year's reviews.
> 
> Please note that patch 0006 and 0008 depend on patch 0005 as they need the
> registers.h file, but belong to different driver areas. I'm not sure if
> I'm supposed to squash them even if they belong to different driver
> areas of if it's fine like this. Any advice is welcome.
> 
> Patch 0009 also depends on patch 0003 because of mt6392-regulator.h.
> 
> The series has been tested on Xiaomi Mi Smart Clock X04G and on the
> Lenovo Smart Clock 2 CD-24502F.
> 

While series is

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

Thanks!
Angelo


> Changes in v9:
> - Correct binding for vrtc as it does not support mode setting.
> 
>  From sashiko:
> - Added missing include in MFD documentation example.
> - Fixed constraints for regulator-initial-mode in regulator binding.
> - Fixed wrong register write while setting LDO standby mode.
> - Added missing pmic interrupt definition in the pumpkin-common include.
> 
> Changes in v8 [9]:
>  From reviewers:
> - Added example code to the MFD device binding, removed it from the
>    regulators docs.
> - Added minItems/maxItems constraints on the regulator mode definitions,
>    improved the mode constants.
> - Fixed formatting issues in the regulator binding.
> - Import the mt6392.dtsi file in pumpkin-common.dtsi, as it was originally
>    meant in [8].
> 
>  From sashiko:
> - Added more explicit constraints on the regulator modes definitions.
> - Use the appropriate modeget register for LDO regulators, Buck registers
>    don't have the corresponding register according to the data sheet.
> - Added the missing of_map_mode function.
> - Removed some debugging code that had no use and masked error codes.
> 
> Changes in v7 [7]:
> - Removed patch 0008 dependency on patch 0003.
> - Reintroduced the regulator driver. In earlier revisions of this series,
>    it was proposed to remove the dedicated compatible for the regulator
>    device [3]. The driver does not use actually it, but it is not possible
>    at this time to remove it from the bindings since it's a required
>    property.
> 
>    Making the regulator-required property conditional was NACKed in [5],
>    with the suggestion to create a separate binding altogether for devices
>    that do not require the compatible property. I tried implementing this,
>    but since the parent device needs to be declared as compatible with
>    mt6323, it leads to a warning in dt_binding_check since mt6323 would
>    be declared as a compatible in both mt6392 and mt6397.
> 
>    In the end the only regulator driver from the mt6397 documentation that
>    still declares an of_match is mt6397-regulator and it does not seem
>    to be necessary, so it should be possible to remove it and make the
>    regulator compatible optional for all regulators, but that change would
>    probably deserve its own separate patch series.
> 
> Changes in v6 [6]:
> - Dropped the regulators driver for the moment
> - Explained the FCHR key name origin in the commit message
> - Introduced the MFD_CELL_* macro in the sub-devices definitions.
>    A separate, independent commit introduced MFD_CELL_* to all the
>    subdevices in the mt6397-core.c file for consistency
> - Replaced of_device_get_match_data with device_get_match_data
> - Removed the mfd_match_data enum in favor of the preexisting
>    chip_id enum
> - Adjusted the error message if the device is unsupported
> 
> Changes in v5 [5]:
> - Double checked regulator driver with data sheet and Android sources.
>    The data sheet I have misses a lot of register descriptions, but
>    Android sources have been helpful to fill the gaps
> - Reintroduced the required attribute for the regulator compatible
>    in the bindings
> - Fixed the missing reference to the MT6392 schema
> - Fixed casts/unused vars reported by kernel test robot
> - Removed Reviewed-by tags from the regulator patches as they have been
>    modified in this version
> 
> Changes in v4 [4]:
> - Dropped usage of the regulator compatible
> - Fixed commit messages text to properly reference the target subsystem
> - Added supply rails to the regulator
> - Reworked the regulator schema and PMIC dtsi. Now all supplies are
>    documented and the schema no longer includes voltage information
> - Removed redundant ldo- / buck- prefixes
> - Renamed the pinfunc header to mediatek,mt6392-pinfunc.h
> - Modified the MFD driver to use a simple identifier in the of_match
>    data properties
> 
> Changes in v3 [3]:
> - Added pinctrl device
> - Changed mt6397-rtc fallback to mt6323-rtc
> - Added schema for regulators
> - Fixed checkpatch issues
> 
> Changes in v2 [2]:
> - Replaced explicit compatibles with fallbacks
> 
> Initial version: [1]
> 
> [1] https://lore.kernel.org/linux-mediatek/cover.1771865014.git.l.scorcia@gmail.com/
> [2] https://lore.kernel.org/linux-mediatek/20260306120521.163654-1-l.scorcia@gmail.com/
> [3] https://lore.kernel.org/linux-mediatek/20260317184507.523060-1-l.scorcia@gmail.com/
> [4] https://lore.kernel.org/linux-mediatek/20260330083429.359819-1-l.scorcia@gmail.com/
> [5] https://lore.kernel.org/linux-mediatek/20260420213529.1645560-1-l.scorcia@gmail.com/
> [6] https://lore.kernel.org/linux-mediatek/20260612200717.361018-1-l.scorcia@gmail.com/
> [7] https://lore.kernel.org/linux-mediatek/20260615071836.362883-1-l.scorcia@gmail.com/
> [8] https://lore.kernel.org/linux-mediatek/20190323211612.860-25-fparent@baylibre.com/
> [9] https://lore.kernel.org/linux-mediatek/20260620200032.334192-1-l.scorcia@gmail.com/
> 
> Fabien Parent (3):
>    dt-bindings: input: mtk-pmic-keys: Add MT6392 PMIC keys
>    mfd: mt6397: Add support for MT6392 PMIC
>    regulator: Add MediaTek MT6392 regulator
> 
> Luca Leonardo Scorcia (4):
>    dt-bindings: mfd: mt6397: Add MT6392 PMIC
>    regulator: dt-bindings: Add MediaTek MT6392 PMIC
>    mfd: mt6397: Use MFD_CELL_* to describe sub-devices
>    pinctrl: mediatek: mt6397: Add MediaTek MT6392
> 
> Val Packett (2):
>    input: keyboard: mtk-pmic-keys: Add MT6392 support
>    arm64: dts: mediatek: Add MediaTek MT6392 PMIC dtsi
> 
>   .../bindings/input/mediatek,pmic-keys.yaml    |   1 +
>   .../bindings/mfd/mediatek,mt6397.yaml         |  75 ++
>   .../regulator/mediatek,mt6392-regulator.yaml  | 112 +++
>   arch/arm64/boot/dts/mediatek/mt6392.dtsi      | 145 ++++
>   .../boot/dts/mediatek/pumpkin-common.dtsi     |   7 +
>   drivers/input/keyboard/mtk-pmic-keys.c        |  17 +
>   drivers/mfd/mt6397-core.c                     | 295 ++++---
>   drivers/mfd/mt6397-irq.c                      |   8 +
>   drivers/pinctrl/mediatek/pinctrl-mt6397.c     |  37 +-
>   drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h |  64 ++
>   drivers/regulator/Kconfig                     |   9 +
>   drivers/regulator/Makefile                    |   1 +
>   drivers/regulator/mt6392-regulator.c          | 764 ++++++++++++++++++
>   .../regulator/mediatek,mt6392-regulator.h     |  23 +
>   include/linux/mfd/mt6392/core.h               |  43 +
>   include/linux/mfd/mt6392/registers.h          | 488 +++++++++++
>   include/linux/mfd/mt6397/core.h               |   1 +
>   include/linux/regulator/mt6392-regulator.h    |  42 +
>   18 files changed, 1970 insertions(+), 162 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/regulator/mediatek,mt6392-regulator.yaml
>   create mode 100644 arch/arm64/boot/dts/mediatek/mt6392.dtsi
>   create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h
>   create mode 100644 drivers/regulator/mt6392-regulator.c
>   create mode 100644 include/dt-bindings/regulator/mediatek,mt6392-regulator.h
>   create mode 100644 include/linux/mfd/mt6392/core.h
>   create mode 100644 include/linux/mfd/mt6392/registers.h
>   create mode 100644 include/linux/regulator/mt6392-regulator.h
> 

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox