From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Hans de Goede <hdegoede@redhat.com>
Cc: Jiri Kosina <jikos@kernel.org>,
Benjamin Tissoires <benjamin.tissoires@redhat.com>,
linux-input@vger.kernel.org
Subject: Re: [PATCH v2 2/4] Input: icn8318 - Add support for icn8505
Date: Sun, 18 Jun 2017 15:06:14 -0700 [thread overview]
Message-ID: <20170618220614.GC40590@dtor-ws> (raw)
In-Reply-To: <20170618101829.18734-2-hdegoede@redhat.com>
On Sun, Jun 18, 2017 at 12:18:27PM +0200, Hans de Goede wrote:
> The icn8505 variant found on some x86 tablets has almost the same protocol
> as the 8318, protocol wise there are only a few small differences:
>
> 1) The 8505 uses 16 bit register addresses and has a different register
> address for the location of the touch data.
> 2) The 8505 coordinates are in little-endian format instead of in be.
> 3) The 8505 allows reading the resolution back from the controller
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> Changes in v2:
> -Read resolution directly from the controller
> ---
> .../bindings/input/touchscreen/chipone_icn8318.txt | 2 +-
> drivers/input/touchscreen/Kconfig | 3 +-
> drivers/input/touchscreen/chipone_icn8318.c | 81 ++++++++++++++++++----
> 3 files changed, 69 insertions(+), 17 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/chipone_icn8318.txt b/Documentation/devicetree/bindings/input/touchscreen/chipone_icn8318.txt
> index d11f8d615b5d..9fdd80749386 100644
> --- a/Documentation/devicetree/bindings/input/touchscreen/chipone_icn8318.txt
> +++ b/Documentation/devicetree/bindings/input/touchscreen/chipone_icn8318.txt
> @@ -1,7 +1,7 @@
> * ChipOne icn8318 I2C touchscreen controller
>
> Required properties:
> - - compatible : "chipone,icn8318"
> + - compatible : "chipone,icn8318" or "chipone,icn8505"
> - reg : I2C slave address of the chip (0x40)
> - interrupt-parent : a phandle pointing to the interrupt controller
> serving the interrupt for this chip
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index cf26ca49ae6d..fff1467506e7 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -157,7 +157,8 @@ config TOUCHSCREEN_CHIPONE_ICN8318
> depends on I2C
> depends on OF
> help
> - Say Y here if you have a ChipOne icn8318 based I2C touchscreen.
> + Say Y here if you have a ChipOne icn8318 or icn8505 based
> + I2C touchscreen.
>
> If unsure, say N.
>
> diff --git a/drivers/input/touchscreen/chipone_icn8318.c b/drivers/input/touchscreen/chipone_icn8318.c
> index ddaae91f02fc..43cc38734d8e 100644
> --- a/drivers/input/touchscreen/chipone_icn8318.c
> +++ b/drivers/input/touchscreen/chipone_icn8318.c
> @@ -1,7 +1,7 @@
> /*
> * Driver for ChipOne icn8318 i2c touchscreen controller
> *
> - * Copyright (c) 2015 Red Hat Inc.
> + * Copyright (c) 2015-2017 Red Hat Inc.
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> @@ -20,6 +20,7 @@
> #include <linux/input/touchscreen.h>
> #include <linux/module.h>
> #include <linux/of.h>
> +#include <linux/of_device.h>
>
> #define ICN8318_REG_POWER 4
> #define ICN8318_REG_TOUCHDATA 16
> @@ -30,6 +31,14 @@
>
> #define ICN8318_MAX_TOUCHES 5
>
> +#define ICN8505_REG_TOUCHDATA 0x1000
> +#define ICN8505_REG_CONFIGDATA 0x8000
> +
> +enum icn8318_model {
> + ICN8318,
> + ICN8505,
> +};
> +
> struct icn8318_touch {
> __u8 slot;
> __be16 x;
> @@ -54,27 +63,37 @@ struct icn8318_data {
> struct input_dev *input;
> struct gpio_desc *wake_gpio;
> struct touchscreen_properties prop;
> + enum icn8318_model model;
> + int touchdata_reg;
> };
>
> -static int icn8318_read_touch_data(struct i2c_client *client,
> - struct icn8318_touch_data *touch_data)
> +static int icn8318_read_data(struct icn8318_data *data, int reg,
> + void *buf, int len)
> {
> - u8 reg = ICN8318_REG_TOUCHDATA;
> + u8 addr[2];
> struct i2c_msg msg[2] = {
> {
> - .addr = client->addr,
> - .len = 1,
> - .buf = ®
> + .addr = data->client->addr,
> + .buf = addr
> },
> {
> - .addr = client->addr,
> + .addr = data->client->addr,
> .flags = I2C_M_RD,
> - .len = sizeof(struct icn8318_touch_data),
> - .buf = (u8 *)touch_data
> + .len = len,
> + .buf = buf
> }
> };
>
> - return i2c_transfer(client->adapter, msg, 2);
> + if (data->model == ICN8318) {
> + addr[0] = reg;
> + msg[0].len = 1;
> + } else {
> + addr[0] = reg >> 8;
> + addr[1] = reg & 0xff;
> + msg[0].len = 2;
> + }
> +
> + return i2c_transfer(data->client->adapter, msg, 2);
> }
>
> static inline bool icn8318_touch_active(u8 event)
> @@ -83,6 +102,14 @@ static inline bool icn8318_touch_active(u8 event)
> (event == ICN8318_EVENT_UPDATE2);
> }
>
> +static u16 icn8318_coord_to_cpu(struct icn8318_data *data, __be16 coord)
> +{
> + if (data->model == ICN8318)
> + return be16_to_cpu(coord);
> + else
> + return le16_to_cpu((__force __le16)coord);
Hmm, this is quite ugly now. I'd drop the __be16 designations on
touch->x/y, made them u8 x[2], y[2], and used get_unaligned_le16() and
get_unaligned_be16() on them...
I also wonder if it would not be cleaner if instead of model constant
you used cost struct with pointers and other chip-specific data.
> +}
> +
> static irqreturn_t icn8318_irq(int irq, void *dev_id)
> {
> struct icn8318_data *data = dev_id;
> @@ -90,7 +117,8 @@ static irqreturn_t icn8318_irq(int irq, void *dev_id)
> struct icn8318_touch_data touch_data;
> int i, ret;
>
> - ret = icn8318_read_touch_data(data->client, &touch_data);
> + ret = icn8318_read_data(data, data->touchdata_reg,
> + &touch_data, sizeof(touch_data));
> if (ret < 0) {
> dev_err(dev, "Error reading touch data: %d\n", ret);
> return IRQ_HANDLED;
> @@ -122,8 +150,9 @@ static irqreturn_t icn8318_irq(int irq, void *dev_id)
> continue;
>
> touchscreen_report_pos(data->input, &data->prop,
> - be16_to_cpu(touch->x),
> - be16_to_cpu(touch->y), true);
> + icn8318_coord_to_cpu(data, touch->x),
> + icn8318_coord_to_cpu(data, touch->y),
> + true);
> }
>
> input_mt_sync_frame(data->input);
> @@ -187,6 +216,8 @@ static int icn8318_probe_of(struct icn8318_data *data, struct device *dev)
> {
> int error;
>
> + data->model = (long)of_device_get_match_data(dev);
> +
> data->wake_gpio = devm_gpiod_get(dev, "wake", GPIOD_OUT_LOW);
> if (IS_ERR(data->wake_gpio)) {
> error = PTR_ERR(data->wake_gpio);
> @@ -210,6 +241,7 @@ static int icn8318_probe(struct i2c_client *client)
> struct icn8318_data *data;
> struct input_dev *input;
> int error;
> + __le16 resolution[2];
>
> if (!client->irq) {
> dev_err(dev, "Error no irq specified\n");
> @@ -240,6 +272,24 @@ static int icn8318_probe(struct i2c_client *client)
> if (error)
> return error;
>
> + if (data->model == ICN8318) {
> + data->touchdata_reg = ICN8318_REG_TOUCHDATA;
> + } else {
> + data->touchdata_reg = ICN8505_REG_TOUCHDATA;
> +
> + error = icn8318_read_data(data, ICN8505_REG_CONFIGDATA,
> + resolution, sizeof(resolution));
> + if (error < 0) {
> + dev_err(dev, "Error reading resolution: %d\n", error);
> + return error;
> + }
> +
> + input_set_abs_params(input, ABS_MT_POSITION_X, 0,
> + le16_to_cpu(resolution[0]) - 1, 0, 0);
> + input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
> + le16_to_cpu(resolution[1]) - 1, 0, 0);
> + }
> +
> touchscreen_parse_properties(input, true, &data->prop);
> if (!input_abs_get_max(input, ABS_MT_POSITION_X) ||
> !input_abs_get_max(input, ABS_MT_POSITION_Y)) {
> @@ -274,7 +324,8 @@ static int icn8318_probe(struct i2c_client *client)
> }
>
> static const struct of_device_id icn8318_of_match[] = {
> - { .compatible = "chipone,icn8318" },
> + { .compatible = "chipone,icn8318", .data = (void *)ICN8318 },
> + { .compatible = "chipone,icn8505", .data = (void *)ICN8505 },
> { }
> };
> MODULE_DEVICE_TABLE(of, icn8318_of_match);
> --
> 2.13.0
>
--
Dmitry
next prev parent reply other threads:[~2017-06-18 22:06 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-18 10:18 [PATCH v2 1/4] Input: icn8318 - Move of specific probe code to a helper function Hans de Goede
2017-06-18 10:18 ` [PATCH v2 2/4] Input: icn8318 - Add support for icn8505 Hans de Goede
2017-06-18 22:06 ` Dmitry Torokhov [this message]
2017-07-06 19:35 ` Hans de Goede
2017-06-18 10:18 ` [PATCH v2 3/4] Input: icn8318 - Add support for ACPI enumeration Hans de Goede
2017-06-18 21:58 ` Dmitry Torokhov
2017-07-06 19:38 ` Hans de Goede
2017-06-18 10:18 ` [PATCH v2 4/4] Input: icn8318 - Add support for capacative home button Hans de Goede
2017-06-18 21:55 ` [PATCH v2 1/4] Input: icn8318 - Move of specific probe code to a helper function Dmitry Torokhov
2017-07-06 19:34 ` Hans de Goede
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=20170618220614.GC40590@dtor-ws \
--to=dmitry.torokhov@gmail.com \
--cc=benjamin.tissoires@redhat.com \
--cc=hdegoede@redhat.com \
--cc=jikos@kernel.org \
--cc=linux-input@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;
as well as URLs for NNTP newsgroup(s).