Skip to content

Commit eca3be9

Browse files
jwrdegoededtor
authored andcommitted
Input: silead - add support for capactive home button found on some x86 tablets
On some x86 tablets with a silead touchscreen the windows logo on the front is a capacitive home button. Touching this button results in a touch with bits 12-15 of the Y coordinates set, while normally only the lower 12 are used. Detect this and report a KEY_LEFTMETA press when this happens. Note for now we only respond to the Y coordinate bits 12-15 containing 0x01, on some tablets *without* a capacative button I've noticed these bits containing 0x04 when crossing the edges of the screen. Acked-by: Rob Herring <[email protected]> Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent da7bdec commit eca3be9

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Optional properties:
2323
- touchscreen-inverted-y : See touchscreen.txt
2424
- touchscreen-swapped-x-y : See touchscreen.txt
2525
- silead,max-fingers : maximum number of fingers the touchscreen can detect
26+
- silead,home-button : Boolean, set to true on devices which have a
27+
capacitive home-button build into the touchscreen
2628
- vddio-supply : regulator phandle for controller VDDIO
2729
- avdd-supply : regulator phandle for controller AVDD
2830

drivers/input/touchscreen/silead.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
#define SILEAD_POINT_Y_MSB_OFF 0x01
5757
#define SILEAD_POINT_X_OFF 0x02
5858
#define SILEAD_POINT_X_MSB_OFF 0x03
59-
#define SILEAD_TOUCH_ID_MASK 0xF0
59+
#define SILEAD_EXTRA_DATA_MASK 0xF0
6060

6161
#define SILEAD_CMD_SLEEP_MIN 10000
6262
#define SILEAD_CMD_SLEEP_MAX 20000
@@ -109,6 +109,9 @@ static int silead_ts_request_input_dev(struct silead_ts_data *data)
109109
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED |
110110
INPUT_MT_TRACK);
111111

112+
if (device_property_read_bool(dev, "silead,home-button"))
113+
input_set_capability(data->input, EV_KEY, KEY_LEFTMETA);
114+
112115
data->input->name = SILEAD_TS_NAME;
113116
data->input->phys = "input/ts";
114117
data->input->id.bustype = BUS_I2C;
@@ -139,7 +142,8 @@ static void silead_ts_read_data(struct i2c_client *client)
139142
struct input_dev *input = data->input;
140143
struct device *dev = &client->dev;
141144
u8 *bufp, buf[SILEAD_TS_DATA_LEN];
142-
int touch_nr, error, i;
145+
int touch_nr, softbutton, error, i;
146+
bool softbutton_pressed = false;
143147

144148
error = i2c_smbus_read_i2c_block_data(client, SILEAD_REG_DATA,
145149
SILEAD_TS_DATA_LEN, buf);
@@ -148,21 +152,40 @@ static void silead_ts_read_data(struct i2c_client *client)
148152
return;
149153
}
150154

151-
touch_nr = buf[0];
152-
if (touch_nr > data->max_fingers) {
155+
if (buf[0] > data->max_fingers) {
153156
dev_warn(dev, "More touches reported then supported %d > %d\n",
154-
touch_nr, data->max_fingers);
155-
touch_nr = data->max_fingers;
157+
buf[0], data->max_fingers);
158+
buf[0] = data->max_fingers;
156159
}
157160

161+
touch_nr = 0;
158162
bufp = buf + SILEAD_POINT_DATA_LEN;
159-
for (i = 0; i < touch_nr; i++, bufp += SILEAD_POINT_DATA_LEN) {
160-
/* Bits 4-7 are the touch id */
161-
data->id[i] = (bufp[SILEAD_POINT_X_MSB_OFF] &
162-
SILEAD_TOUCH_ID_MASK) >> 4;
163-
touchscreen_set_mt_pos(&data->pos[i], &data->prop,
163+
for (i = 0; i < buf[0]; i++, bufp += SILEAD_POINT_DATA_LEN) {
164+
softbutton = (bufp[SILEAD_POINT_Y_MSB_OFF] &
165+
SILEAD_EXTRA_DATA_MASK) >> 4;
166+
167+
if (softbutton) {
168+
/*
169+
* For now only respond to softbutton == 0x01, some
170+
* tablets *without* a capacative button send 0x04
171+
* when crossing the edges of the screen.
172+
*/
173+
if (softbutton == 0x01)
174+
softbutton_pressed = true;
175+
176+
continue;
177+
}
178+
179+
/*
180+
* Bits 4-7 are the touch id, note not all models have
181+
* hardware touch ids so atm we don't use these.
182+
*/
183+
data->id[touch_nr] = (bufp[SILEAD_POINT_X_MSB_OFF] &
184+
SILEAD_EXTRA_DATA_MASK) >> 4;
185+
touchscreen_set_mt_pos(&data->pos[touch_nr], &data->prop,
164186
get_unaligned_le16(&bufp[SILEAD_POINT_X_OFF]) & 0xfff,
165187
get_unaligned_le16(&bufp[SILEAD_POINT_Y_OFF]) & 0xfff);
188+
touch_nr++;
166189
}
167190

168191
input_mt_assign_slots(input, data->slots, data->pos, touch_nr, 0);
@@ -178,6 +201,7 @@ static void silead_ts_read_data(struct i2c_client *client)
178201
}
179202

180203
input_mt_sync_frame(input);
204+
input_report_key(input, KEY_LEFTMETA, softbutton_pressed);
181205
input_sync(input);
182206
}
183207

0 commit comments

Comments
 (0)