[PATCH 6/6] Input: mms114 - refactor chip variant handling using descriptors
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Date: 2026-06-16 05:09:23
Also in:
lkml
Subsystem:
input (keyboard, mouse, joystick, touchscreen) drivers, the rest · Maintainers:
Dmitry Torokhov, Linus Torvalds
Instead of using an enum and conditional switch/if statements throughout the driver to handle differences between chip variants (MMS114, MMS134S, MMS136, MMS152, MMS345L), introduce a variant-specific descriptor structure that encapsulates variant-specific properties (name, event size, presence of configuration registers) and callbacks (such as get_version). Define descriptors for each supported chip and associate them with the matching entries in the OF and I2C device ID tables. This eliminates the need for variant checks in the driver logic, making it easier to support new chip variants in the future. Assisted-by: Antigravity:gemini-3.5-flash Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/touchscreen/mms114.c | 204 ++++++++++++++++------------- 1 file changed, 112 insertions(+), 92 deletions(-)
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index bf01eee0560a..006dded17eb8 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c@@ -52,21 +52,13 @@ #define MMS114_TYPE_TOUCHSCREEN 1 #define MMS114_TYPE_TOUCHKEY 2 -enum mms_type { - TYPE_MMS114 = 114, - TYPE_MMS134S = 134, - TYPE_MMS136 = 136, - TYPE_MMS152 = 152, - TYPE_MMS345L = 345, -}; - struct mms114_data { + const struct mms_chip *chip; struct i2c_client *client; struct input_dev *input_dev; struct regulator *core_reg; struct regulator *io_reg; struct touchscreen_properties props; - enum mms_type type; unsigned int contact_threshold; unsigned int moving_threshold;
@@ -77,6 +69,13 @@ struct mms114_data { u8 cache_mode_control; }; +struct mms_chip { + const char *name; + int event_size; + bool has_config_regs; + int (*get_version)(struct mms114_data *data); +}; + struct mms114_touch { u8 id:4, reserved_bit4:1, type:2, pressed:1; u8 x_hi:4, y_hi:4;
@@ -156,6 +155,91 @@ static int mms114_write_reg(struct mms114_data *data, u8 reg, u8 val) return 0; } +static int mms114_get_version(struct mms114_data *data) +{ + struct device *dev = &data->client->dev; + u8 buf[6]; + int error; + + error = __mms114_read_reg(data, MMS114_TSP_REV, 6, buf); + if (error) + return error; + + dev_info(dev, "TSP Rev: 0x%x, HW Rev: 0x%x, Firmware Ver: 0x%x\n", + buf[0], buf[1], buf[3]); + return 0; +} + +static int mms152_get_version(struct mms114_data *data) +{ + struct device *dev = &data->client->dev; + u8 buf[3]; + int group; + int error; + + error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf); + if (error) + return error; + + group = i2c_smbus_read_byte_data(data->client, MMS152_COMPAT_GROUP); + if (group < 0) + return group; + + dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x, Compat group: %c\n", + buf[0], buf[1], buf[2], group); + return 0; +} + +static int mms345l_get_version(struct mms114_data *data) +{ + struct device *dev = &data->client->dev; + u8 buf[3]; + int error; + + error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf); + if (error) + return error; + + dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x\n", + buf[0], buf[1], buf[2]); + return 0; +} + +static const struct mms_chip mms114_descriptor = { + .name = "MMS114", + .event_size = MMS114_EVENT_SIZE, + .has_config_regs = true, + .get_version = mms114_get_version, +}; + +static const struct mms_chip mms134s_descriptor = { + .name = "MMS134S", + .event_size = MMS136_EVENT_SIZE, + .has_config_regs = true, + .get_version = mms114_get_version, +}; + +static const struct mms_chip mms136_descriptor = { + .name = "MMS136", + .event_size = MMS136_EVENT_SIZE, + .has_config_regs = true, + .get_version = mms114_get_version, +}; + +static const struct mms_chip mms152_descriptor = { + .name = "MMS152", + .event_size = MMS114_EVENT_SIZE, + .has_config_regs = false, + .get_version = mms152_get_version, +}; + +static const struct mms_chip mms345l_descriptor = { + .name = "MMS345L", + .event_size = MMS114_EVENT_SIZE, + .has_config_regs = false, + .get_version = mms345l_get_version, +}; + static void mms114_process_mt(struct mms114_data *data, struct mms114_touch *touch) { struct i2c_client *client = data->client;
@@ -217,8 +301,8 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id) struct i2c_client *client = data->client; struct mms114_touch touch[MMS114_MAX_TOUCH]; struct mms114_touch *t; + int event_size = data->chip->event_size; int packet_size; - int event_size; int touch_size; int index; int error;
@@ -233,12 +317,6 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id) goto out; } - /* MMS136 has slightly different event size */ - if (data->type == TYPE_MMS134S || data->type == TYPE_MMS136) - event_size = MMS136_EVENT_SIZE; - else - event_size = MMS114_EVENT_SIZE; - touch_size = packet_size / event_size; error = __mms114_read_reg(data, MMS114_INFORMATION, packet_size, touch);
@@ -288,64 +366,17 @@ static int mms114_set_active(struct mms114_data *data, bool active) return mms114_write_reg(data, MMS114_MODE_CONTROL, val); } -static int mms114_get_version(struct mms114_data *data) -{ - struct device *dev = &data->client->dev; - u8 buf[6]; - int group; - int error; - - switch (data->type) { - case TYPE_MMS345L: - error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf); - if (error) - return error; - - dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x\n", - buf[0], buf[1], buf[2]); - break; - - case TYPE_MMS152: - error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf); - if (error) - return error; - - group = i2c_smbus_read_byte_data(data->client, MMS152_COMPAT_GROUP); - if (group < 0) - return group; - - dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x, Compat group: %c\n", - buf[0], buf[1], buf[2], group); - break; - - case TYPE_MMS114: - case TYPE_MMS134S: - case TYPE_MMS136: - error = __mms114_read_reg(data, MMS114_TSP_REV, 6, buf); - if (error) - return error; - - dev_info(dev, "TSP Rev: 0x%x, HW Rev: 0x%x, Firmware Ver: 0x%x\n", - buf[0], buf[1], buf[3]); - break; - } - - return 0; -} - static int mms114_setup_regs(struct mms114_data *data) { const struct touchscreen_properties *props = &data->props; int val; int error; - error = mms114_get_version(data); - if (error < 0) + error = data->chip->get_version(data); + if (error) return error; - /* MMS114, MMS134S and MMS136 have configuration and power on registers */ - if (data->type != TYPE_MMS114 && data->type != TYPE_MMS134S && - data->type != TYPE_MMS136) + if (!data->chip->has_config_regs) return 0; error = mms114_set_active(data, true);
@@ -481,7 +512,6 @@ static int mms114_probe(struct i2c_client *client) { struct mms114_data *data; struct input_dev *input_dev; - const void *match_data; int error; int i;
@@ -501,12 +531,10 @@ static int mms114_probe(struct i2c_client *client) data->client = client; data->input_dev = input_dev; - match_data = device_get_match_data(&client->dev); - if (!match_data) + data->chip = i2c_get_match_data(client); + if (!data->chip) return -EINVAL; - data->type = (enum mms_type)match_data; - data->num_keycodes = device_property_count_u32(&client->dev, "linux,keycodes"); if (data->num_keycodes == -EINVAL) {
@@ -563,8 +591,7 @@ static int mms114_probe(struct i2c_client *client) 0, data->props.max_y, 0, 0); } - if (data->type == TYPE_MMS114 || data->type == TYPE_MMS134S || - data->type == TYPE_MMS136) { + if (data->chip->has_config_regs) { /* * The firmware handles movement and pressure fuzz, so * don't duplicate that in software.
@@ -579,8 +606,8 @@ static int mms114_probe(struct i2c_client *client) } input_dev->name = devm_kasprintf(&client->dev, GFP_KERNEL, - "MELFAS MMS%d Touchscreen", - data->type); + "MELFAS %s Touchscreen", + data->chip->name); if (!input_dev->name) return -ENOMEM;
@@ -676,29 +703,22 @@ static int mms114_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(mms114_pm_ops, mms114_suspend, mms114_resume); static const struct i2c_device_id mms114_id[] = { - { .name = "mms114" }, + { .name = "mms114", .driver_data = (kernel_ulong_t)&mms114_descriptor }, + { .name = "mms134s", .driver_data = (kernel_ulong_t)&mms134s_descriptor }, + { .name = "mms136", .driver_data = (kernel_ulong_t)&mms136_descriptor }, + { .name = "mms152", .driver_data = (kernel_ulong_t)&mms152_descriptor }, + { .name = "mms345l", .driver_data = (kernel_ulong_t)&mms345l_descriptor }, { } }; MODULE_DEVICE_TABLE(i2c, mms114_id); #ifdef CONFIG_OF static const struct of_device_id mms114_dt_match[] = { - { - .compatible = "melfas,mms114", - .data = (void *)TYPE_MMS114, - }, { - .compatible = "melfas,mms134s", - .data = (void *)TYPE_MMS134S, - }, { - .compatible = "melfas,mms136", - .data = (void *)TYPE_MMS136, - }, { - .compatible = "melfas,mms152", - .data = (void *)TYPE_MMS152, - }, { - .compatible = "melfas,mms345l", - .data = (void *)TYPE_MMS345L, - }, + { .compatible = "melfas,mms114", .data = &mms114_descriptor }, + { .compatible = "melfas,mms134s", .data = &mms134s_descriptor }, + { .compatible = "melfas,mms136", .data = &mms136_descriptor }, + { .compatible = "melfas,mms152", .data = &mms152_descriptor }, + { .compatible = "melfas,mms345l", .data = &mms345l_descriptor }, { } }; MODULE_DEVICE_TABLE(of, mms114_dt_match);
--
2.54.0.1136.gdb2ca164c4-goog