Commit c1ca2174 authored by Adya's avatar Adya

Working TS reporting Pen tools when necessary (+ .gitignore)

parent 875783fc
.*
!.gitignore
*.ko
*.mod.c
*.mod.o
*.o
*.symvers
*.order
\ No newline at end of file
......@@ -40,7 +40,6 @@ struct goodix_chip_data {
struct goodix_ts_data {
struct i2c_client *client;
struct input_dev *input_dev;
struct input_dev *pen_dev;
const struct goodix_chip_data *chip;
struct touchscreen_properties prop;
unsigned int max_touch_num;
......@@ -58,6 +57,8 @@ struct goodix_ts_data {
#define GOODIX_STYLUS_BTN1 0
#define GOODIX_STYLUS_BTN2 1
#define GOODIX_KEYDOWN_EVENT(byte) \
(byte & 0b01110000)
#define GOODIX_IS_STYLUS_BTN_DOWN(byte, btn) \
((byte & 0x40) || (byte & (0b1 << btn)))
......@@ -67,6 +68,9 @@ struct goodix_ts_data {
#define GOODIX_TOOL_TYPE(id_byte) \
(id_byte & 0x80 ? GOODIX_TOOL_PEN : GOODIX_TOOL_FINGER)
#define GOODIX_TOOL_TYPE_TO_MT_TOOL(tool_type) \
(tool_type == GOODIX_TOOL_PEN ? MT_TOOL_PEN : MT_TOOL_FINGER)
#define GOODIX_TOOL_TYPE_TO_STRING(tool_type) \
(tool_type == GOODIX_TOOL_FINGER ? "Finger" : \
(tool_type == GOODIX_TOOL_PEN ? "Pen" : "" ))
......@@ -94,7 +98,8 @@ struct goodix_input_report {
#define GOODIX_MAX_WIDTH 4096
#define GOODIX_INT_TRIGGER 1
#define GOODIX_CONTACT_SIZE 8
#define GOODIX_MAX_CONTACTS 10
#define GOODIX_MAX_CONTACTS 11
#define GOODIX_STYLUS_POINT_ID GOODIX_MAX_CONTACTS - 1
#define GOODIX_CONFIG_MAX_LENGTH 240
#define GOODIX_CONFIG_911_LENGTH 186
......@@ -278,7 +283,10 @@ static void goodix_populate_report(u8 *data, struct goodix_input_report *report)
for (i = 0; i < report->touch_num; i++) {
point_data = &data[1 + i * GOODIX_CONTACT_SIZE];
report->points[i] = (struct goodix_point){
.id = point_data[0] & 0x0f,
.id = (
GOODIX_TOOL_TYPE(point_data[0]) == GOODIX_TOOL_PEN ?
GOODIX_STYLUS_POINT_ID : point_data[0] & 0x0f
),
.tool_type = GOODIX_TOOL_TYPE(point_data[0]),
.x = point_data[1] | (point_data[2] << 8),
.y = point_data[3] | (point_data[4] << 8),
......@@ -361,28 +369,38 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
return 0;
}
static void goodix_ts_report_touch(struct goodix_ts_data *ts,
struct goodix_point *point)
static void goodix_ts_report_mt_slots(struct goodix_ts_data *ts,
struct goodix_input_report *report)
{
switch (point->tool_type) {
case GOODIX_TOOL_PEN:
input_report_key(ts->pen_dev, BTN_TOOL_PEN, 1);
input_report_key(ts->pen_dev, BTN_TOUCH, point->w > 0 ? 1 : 0);
input_report_abs(ts->pen_dev, ABS_X, point->x);
input_report_abs(ts->pen_dev, ABS_Y, point->y);
input_report_abs(ts->pen_dev, ABS_PRESSURE, point->w);
break;
case GOODIX_TOOL_FINGER:
default:
int i;
struct goodix_point *point = report->points;
u16 cur_touch = 0;
static u16 prev_touch;
for (i = 0; i < GOODIX_MAX_CONTACTS; i++) {
if (report->touch_num && i == point->id) {
input_mt_slot(ts->input_dev, point->id);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
touchscreen_report_pos(ts->input_dev, &ts->prop,
point->x, point->y, true);
input_mt_report_slot_state(ts->input_dev,
GOODIX_TOOL_TYPE_TO_MT_TOOL(point->tool_type), true);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, point->x);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, point->y);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, point->w);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, point->w);
break;
input_report_abs(ts->input_dev, ABS_MT_PRESSURE, point->w);
cur_touch |= 0b1 << point->id;
point++;
}
else if (prev_touch & 0b1 << i) {
input_mt_slot(ts->input_dev, i);
input_mt_report_slot_state(ts->input_dev,
(i == GOODIX_STYLUS_POINT_ID ? MT_TOOL_PEN : MT_TOOL_FINGER),
false);
}
}
prev_touch = cur_touch;
input_mt_sync_frame(ts->input_dev);
input_sync(ts->input_dev);
}
/**
......@@ -399,14 +417,14 @@ static void goodix_process_events(struct goodix_ts_data *ts)
struct goodix_point points[GOODIX_MAX_CONTACTS];
struct goodix_input_report report = { .points = points };
int touch_num;
int i;
static u8 prev_keys = 0;
touch_num = goodix_ts_read_input_report(ts, point_data);
if (touch_num < 0)
return;
goodix_populate_report(point_data, &report);
// goodix_dump_report(ts, &report);
goodix_dump_report(ts, &report);
/*
* Bit 4 of the first byte reports the status of the capacitive
......@@ -419,16 +437,15 @@ static void goodix_process_events(struct goodix_ts_data *ts)
&point_data[1 + GOODIX_CONTACT_SIZE * i]);
*/
input_report_key(ts->pen_dev, BTN_STYLUS,
GOODIX_IS_STYLUS_BTN_DOWN(report.keys, GOODIX_STYLUS_BTN1));
input_report_key(ts->pen_dev, BTN_STYLUS2,
GOODIX_IS_STYLUS_BTN_DOWN(report.keys, GOODIX_STYLUS_BTN2));
for (i = 0; i < touch_num; i++)
goodix_ts_report_touch(ts, &report.points[i]);
if (GOODIX_KEYDOWN_EVENT(report.keys) || GOODIX_KEYDOWN_EVENT(prev_keys)) {
input_report_key(ts->input_dev, BTN_STYLUS,
GOODIX_IS_STYLUS_BTN_DOWN(report.keys, GOODIX_STYLUS_BTN1));
input_report_key(ts->input_dev, BTN_STYLUS2,
GOODIX_IS_STYLUS_BTN_DOWN(report.keys, GOODIX_STYLUS_BTN2));
prev_keys = report.keys;
}
input_mt_sync_frame(ts->input_dev);
input_sync(ts->input_dev);
goodix_ts_report_mt_slots(ts, &report);
}
/**
......@@ -794,37 +811,27 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
ts->input_dev->id.product = ts->id;
ts->input_dev->id.version = ts->version;
ts->input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
ts->input_dev->evbit[0] |= BIT_MASK(EV_SYN)
| BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
__set_bit(BTN_TOOL_PEN, ts->input_dev->keybit);
__set_bit(BTN_STYLUS, ts->input_dev->keybit);
__set_bit(BTN_STYLUS2, ts->input_dev->keybit);
__set_bit(BTN_TOUCH, ts->input_dev->keybit);
/* Capacitive Windows/Home button on some devices */
input_set_capability(ts->input_dev, EV_KEY, KEY_LEFTMETA);
input_set_capability(ts->input_dev, EV_KEY, BTN_STYLUS);
input_set_capability(ts->input_dev, EV_KEY, BTN_STYLUS2);
input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_X);
input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_Y);
input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
/* Active stylus pen */
ts->pen_dev = devm_input_allocate_device(&ts->client->dev);
if (!ts->pen_dev) {
dev_err(&ts->client->dev, "Failed to allocate pen device.");
return -ENOMEM;
}
ts->pen_dev->name = "Goodix Active Stylus Pen";
ts->pen_dev->phys = "input/pen";
ts->pen_dev->id.bustype = BUS_I2C;
ts->pen_dev->id.vendor = 0x0416;
ts->pen_dev->id.product = ts->id;
ts->pen_dev->id.version = ts->version;
__set_bit(BTN_TOOL_PEN, ts->pen_dev->keybit);
__set_bit(BTN_STYLUS, ts->pen_dev->keybit);
__set_bit(BTN_STYLUS2, ts->pen_dev->keybit);
__set_bit(BTN_TOUCH, ts->pen_dev->keybit);
input_set_abs_params(ts->pen_dev, ABS_PRESSURE,
0, 1024, 0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0,
1024, 0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_TOOL_TYPE,
0, MT_TOOL_MAX, 0, 0);
/* Read configuration and apply touchscreen parameters */
goodix_read_config(ts);
......@@ -843,12 +850,13 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
ABS_MT_POSITION_X, ts->prop.max_x);
input_abs_set_max(ts->input_dev,
ABS_MT_POSITION_Y, ts->prop.max_y);
input_set_abs_params(ts->pen_dev, ABS_X, 0,
ts->prop.max_x, 0, 0);
input_set_abs_params(ts->pen_dev, ABS_Y, 0,
ts->prop.max_y, 0, 0);
}
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0,
ts->prop.max_x, 0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0,
ts->prop.max_y, 0, 0);
if (dmi_check_system(rotated_screen)) {
ts->prop.invert_x = true;
ts->prop.invert_y = true;
......@@ -871,14 +879,6 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
return error;
}
error = input_register_device(ts->pen_dev);
if (error) {
dev_err(&ts->client->dev,
"Failed to register pen device: %d", error);
input_free_device(ts->input_dev);
return error;
}
ts->irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
error = goodix_request_irq(ts);
if (error) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment