[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20191007205021.104402-1-stephan@gerhold.net>
Date: Mon, 7 Oct 2019 22:50:21 +0200
From: Stephan Gerhold <stephan@...hold.net>
To: Dmitry Torokhov <dmitry.torokhov@...il.com>
Cc: Andi Shyti <andi@...zian.org>, Simon Shields <simon@...eageos.org>,
linux-input@...r.kernel.org, Rob Herring <robh+dt@...nel.org>,
Mark Rutland <mark.rutland@....com>,
devicetree@...r.kernel.org, linux-kernel@...r.kernel.org,
Stephan Gerhold <stephan@...hold.net>
Subject: [PATCH 3/3] Input: mms114 - add support for mms345l
MMS345L is another first generation touch screen from Melfas,
which uses the same registers as MMS152.
However, using I2C_M_NOSTART for it causes errors when reading:
i2c i2c-0: sendbytes: NAK bailout.
mms114 0-0048: __mms114_read_reg: i2c transfer failed (-5)
The driver works fine as soon as I2C_M_NOSTART is removed.
Add a separate melfas,mms345l binding, and make use of I2C_M_NOSTART
only for MMS114 and MMS152.
Signed-off-by: Stephan Gerhold <stephan@...hold.net>
---
Note: I was not able to find a datasheet for any of the models,
so this change is merely based on testing and comparison with
the downstream driver [1].
There was a related patch [2] that removes I2C_M_NOSTART for all models,
but it seems abandoned and I do not have any other model for testing.
Therefore, this patch implements the least instrusive solution
and only removes I2C_M_NOSTART for MMS345L.
[1]: https://github.com/msm8916-mainline/android_kernel_qcom_msm8916/blob/SM-A500FU/drivers/input/touchscreen/mms300_a.c
[2]: https://patchwork.kernel.org/patch/10189541/
---
drivers/input/touchscreen/mms114.c | 43 +++++++++++++++++++++---------
1 file changed, 31 insertions(+), 12 deletions(-)
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 69c6d559eeb0..d9f45755d073 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -54,6 +54,7 @@
enum mms_type {
TYPE_MMS114 = 114,
TYPE_MMS152 = 152,
+ TYPE_MMS345L = 345,
};
struct mms114_data {
@@ -91,9 +92,14 @@ static int __mms114_read_reg(struct mms114_data *data, unsigned int reg,
if (reg <= MMS114_MODE_CONTROL && reg + len > MMS114_MODE_CONTROL)
BUG();
- /* Write register: use repeated start */
+ /* Write register */
xfer[0].addr = client->addr;
- xfer[0].flags = I2C_M_TEN | I2C_M_NOSTART;
+ if (data->type != TYPE_MMS345L)
+ /* use repeated start */
+ xfer[0].flags = I2C_M_TEN | I2C_M_NOSTART;
+ else
+ xfer[0].flags = client->flags & I2C_M_TEN;
+
xfer[0].len = 1;
xfer[0].buf = &buf;
@@ -250,6 +256,15 @@ static int mms114_get_version(struct mms114_data *data)
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)
@@ -287,8 +302,8 @@ static int mms114_setup_regs(struct mms114_data *data)
if (error < 0)
return error;
- /* MMS152 has no configuration or power on registers */
- if (data->type == TYPE_MMS152)
+ /* Only MMS114 has configuration and power on registers */
+ if (data->type != TYPE_MMS114)
return 0;
error = mms114_set_active(data, true);
@@ -425,11 +440,16 @@ static int mms114_probe(struct i2c_client *client,
{
struct mms114_data *data;
struct input_dev *input_dev;
- const void *match_data;
+ enum mms_type type;
int error;
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_PROTOCOL_MANGLING)) {
+ type = (enum mms_type)device_get_match_data(&client->dev);
+ if (!type)
+ return -EINVAL;
+
+ if (type != TYPE_MMS345L &&
+ !i2c_check_functionality(client->adapter,
+ I2C_FUNC_PROTOCOL_MANGLING)) {
dev_err(&client->dev,
"Need i2c bus that supports protocol mangling\n");
return -ENODEV;
@@ -446,11 +466,7 @@ 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)
- return -EINVAL;
-
- data->type = (enum mms_type)match_data;
+ data->type = type;
input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
@@ -599,6 +615,9 @@ static const struct of_device_id mms114_dt_match[] = {
}, {
.compatible = "melfas,mms152",
.data = (void *)TYPE_MMS152,
+ }, {
+ .compatible = "melfas,mms345l",
+ .data = (void *)TYPE_MMS345L,
},
{ }
};
--
2.23.0
Powered by blists - more mailing lists