From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: linux-input@vger.kernel.org
Cc: Linus Walleij <linusw@kernel.org>,
Bryam Vargas <hexlabsecurity@proton.me>,
linux-kernel@vger.kernel.org
Subject: [PATCH 6/6] Input: mms114 - refactor chip variant handling using descriptors
Date: Mon, 15 Jun 2026 22:09:11 -0700 [thread overview]
Message-ID: <20260616050912.1531241-6-dmitry.torokhov@gmail.com> (raw)
In-Reply-To: <20260616050912.1531241-1-dmitry.torokhov@gmail.com>
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
next prev parent reply other threads:[~2026-06-16 5:09 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-16 5:09 [PATCH 1/6] Input: mms114 - fix touch indexing for MMS134S and MMS136 Dmitry Torokhov
2026-06-16 5:09 ` [PATCH 2/6] Input: mms114 - prefer GPL over GPL v2 for module license Dmitry Torokhov
2026-06-16 5:09 ` [PATCH 3/6] Input: mms114 - use appropriate register argument types Dmitry Torokhov
2026-06-16 5:20 ` sashiko-bot
2026-06-16 5:09 ` [PATCH 4/6] Input: mms114 - replace udelay with usleep_range Dmitry Torokhov
2026-06-16 5:20 ` sashiko-bot
2026-06-16 5:09 ` [PATCH 5/6] Input: mms114 - replace BUG() and fix alignment Dmitry Torokhov
2026-06-16 5:27 ` sashiko-bot
2026-06-16 7:21 ` Bryam Vargas
2026-06-16 5:09 ` Dmitry Torokhov [this message]
2026-06-16 5:20 ` [PATCH 6/6] Input: mms114 - refactor chip variant handling using descriptors sashiko-bot
2026-06-16 7:42 ` Bryam Vargas
2026-06-16 5:20 ` [PATCH 1/6] Input: mms114 - fix touch indexing for MMS134S and MMS136 sashiko-bot
2026-06-16 7:05 ` Bryam Vargas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260616050912.1531241-6-dmitry.torokhov@gmail.com \
--to=dmitry.torokhov@gmail.com \
--cc=hexlabsecurity@proton.me \
--cc=linusw@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox