Skip to content

Commit

Permalink
input: touchscreen: zinitix: Add touchkey support
Browse files Browse the repository at this point in the history
Zinitix touch controllers can use some of the sense lines for virtual
keys (like those found on many phones). Add support for those keys.

Signed-off-by: Nikita Travkin <nikita@trvn.ru>
  • Loading branch information
TravMurav authored and intel-lab-lkp committed Oct 27, 2021
1 parent 1b2bd0f commit 4d4045d
Showing 1 changed file with 58 additions and 3 deletions.
61 changes: 58 additions & 3 deletions drivers/input/touchscreen/zinitix.c
Expand Up @@ -119,6 +119,7 @@

#define DEFAULT_TOUCH_POINT_MODE 2
#define MAX_SUPPORTED_FINGER_NUM 5
#define MAX_SUPPORTED_BUTTON_NUM 8

#define CHIP_ON_DELAY 15 // ms
#define FIRMWARE_ON_DELAY 40 // ms
Expand Down Expand Up @@ -146,6 +147,8 @@ struct bt541_ts_data {
struct touchscreen_properties prop;
struct regulator_bulk_data supplies[2];
u32 zinitix_mode;
u32 keycodes[MAX_SUPPORTED_BUTTON_NUM];
int num_keycodes;
};

static int zinitix_read_data(struct i2c_client *client,
Expand Down Expand Up @@ -195,6 +198,7 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
struct i2c_client *client = bt541->client;
int i;
int error;
u16 int_flags = 0;

error = zinitix_write_cmd(client, BT541_SWRESET_CMD);
if (error) {
Expand Down Expand Up @@ -225,6 +229,11 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
if (error)
return error;

error = zinitix_write_u16(client, BT541_BUTTON_SUPPORTED_NUM,
bt541->num_keycodes);
if (error)
return error;

error = zinitix_write_u16(client, BT541_INITIAL_TOUCH_MODE,
bt541->zinitix_mode);
if (error)
Expand All @@ -235,9 +244,12 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
if (error)
return error;

error = zinitix_write_u16(client, BT541_INT_ENABLE_FLAG,
BIT_PT_CNT_CHANGE | BIT_DOWN | BIT_MOVE |
BIT_UP);
int_flags = BIT_PT_CNT_CHANGE | BIT_DOWN | BIT_MOVE | BIT_UP;

if (bt541->num_keycodes)
int_flags |= BIT_ICON_EVENT;

error = zinitix_write_u16(client, BT541_INT_ENABLE_FLAG, int_flags);
if (error)
return error;

Expand Down Expand Up @@ -329,13 +341,23 @@ static void zinitix_report_finger(struct bt541_ts_data *bt541, int slot,
input_report_abs(bt541->input_dev, ABS_MT_TOUCH_MAJOR, p->width);
}

static void zinitix_report_keys(struct bt541_ts_data *bt541, __le16 icon_events)
{
int i;

for (i = 0; i < bt541->num_keycodes; i++)
input_report_key(bt541->input_dev,
bt541->keycodes[i], !!(icon_events & BIT(i)));
}

static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
{
struct bt541_ts_data *bt541 = bt541_handler;
struct i2c_client *client = bt541->client;
struct touch_event touch_event;
int error;
int i;
__le16 icon_events = 0;

memset(&touch_event, 0, sizeof(struct touch_event));

Expand All @@ -346,6 +368,17 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
goto out;
}

if (touch_event.status & BIT_ICON_EVENT) {
error = zinitix_read_data(bt541->client, BT541_ICON_STATUS_REG,
&icon_events, sizeof(icon_events));
if (error) {
dev_err(&client->dev, "Failed to read icon events\n");
goto out;
}

zinitix_report_keys(bt541, icon_events);
}

for (i = 0; i < MAX_SUPPORTED_FINGER_NUM; i++)
if (touch_event.point_coord[i].sub_status & SUB_BIT_EXIST)
zinitix_report_finger(bt541, i,
Expand Down Expand Up @@ -427,6 +460,7 @@ static int zinitix_init_input_dev(struct bt541_ts_data *bt541)
{
struct input_dev *input_dev;
int error;
int i;

input_dev = devm_input_allocate_device(&bt541->client->dev);
if (!input_dev) {
Expand All @@ -444,6 +478,14 @@ static int zinitix_init_input_dev(struct bt541_ts_data *bt541)
input_dev->open = zinitix_input_open;
input_dev->close = zinitix_input_close;

if (bt541->num_keycodes) {
input_dev->keycode = bt541->keycodes;
input_dev->keycodemax = bt541->num_keycodes;
input_dev->keycodesize = sizeof(bt541->keycodes[0]);
for (i = 0; i < bt541->num_keycodes; i++)
input_set_capability(input_dev, EV_KEY, bt541->keycodes[i]);
}

input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
Expand Down Expand Up @@ -508,6 +550,19 @@ static int zinitix_ts_probe(struct i2c_client *client)
return error;
}

bt541->num_keycodes = of_property_read_variable_u32_array(
client->dev.of_node, "linux,keycodes",
bt541->keycodes, 0,
ARRAY_SIZE(bt541->keycodes));
if (bt541->num_keycodes == -EINVAL) {
bt541->num_keycodes = 0;
} else if (bt541->num_keycodes < 0) {
dev_err(&client->dev,
"Unable to parse \"linux,keycodes\" property: %d\n",
bt541->num_keycodes);
return bt541->num_keycodes;
}

error = zinitix_init_input_dev(bt541);
if (error) {
dev_err(&client->dev,
Expand Down

0 comments on commit 4d4045d

Please sign in to comment.