mirror of
https://github.com/andreili/SBC_builder.git
synced 2025-08-23 19:04:06 +02:00
Add no-IRQ mode support for EDT touch.
This commit is contained in:
parent
cd4e03082c
commit
933a2c3d1c
161
patch/kernel/printer_edt_ft5x06_noIRQ_support.patch
Normal file
161
patch/kernel/printer_edt_ft5x06_noIRQ_support.patch
Normal file
@ -0,0 +1,161 @@
|
||||
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
|
||||
index 0d7bf18e2508..535e84de038e 100644
|
||||
--- a/drivers/input/touchscreen/edt-ft5x06.c
|
||||
+++ b/drivers/input/touchscreen/edt-ft5x06.c
|
||||
@@ -77,6 +77,10 @@
|
||||
#define EDT_DEFAULT_NUM_X 1024
|
||||
#define EDT_DEFAULT_NUM_Y 1024
|
||||
|
||||
+#define RESET_DELAY_MS 300 /* reset deassert to I2C */
|
||||
+#define FIRST_POLL_DELAY_MS 300 /* in addition to the above */
|
||||
+#define POLL_INTERVAL_MS 17 /* 17ms = 60fps */
|
||||
+
|
||||
#define M06_REG_CMD(factory) ((factory) ? 0xf3 : 0xfc)
|
||||
#define M06_REG_ADDR(factory, addr) ((factory) ? (addr) & 0x7f : (addr) & 0x3f)
|
||||
|
||||
@@ -135,6 +139,7 @@ struct edt_ft5x06_ts_data {
|
||||
int offset_y;
|
||||
int report_rate;
|
||||
int max_support_points;
|
||||
+ unsigned int known_ids;
|
||||
int point_len;
|
||||
u8 tdata_cmd;
|
||||
int tdata_len;
|
||||
@@ -147,6 +152,9 @@ struct edt_ft5x06_ts_data {
|
||||
enum edt_ver version;
|
||||
unsigned int crc_errors;
|
||||
unsigned int header_errors;
|
||||
+
|
||||
+ struct timer_list timer;
|
||||
+ struct work_struct work_i2c_poll;
|
||||
};
|
||||
|
||||
struct edt_i2c_chip_data {
|
||||
@@ -303,6 +311,10 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
|
||||
u8 rdbuf[63];
|
||||
int i, type, x, y, id;
|
||||
int error;
|
||||
+ unsigned int active_ids = 0, known_ids = tsdata->known_ids;
|
||||
+ long released_ids;
|
||||
+ int b = 0;
|
||||
+ unsigned int num_points;
|
||||
|
||||
memset(rdbuf, 0, sizeof(rdbuf));
|
||||
error = regmap_bulk_read(tsdata->regmap, tsdata->tdata_cmd, rdbuf,
|
||||
@@ -313,7 +325,16 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
|
||||
goto out;
|
||||
}
|
||||
|
||||
- for (i = 0; i < tsdata->max_support_points; i++) {
|
||||
+ /* M09/M12 does not send header or CRC */
|
||||
+ if (tsdata->version == EDT_M06) {
|
||||
+ num_points = tsdata->max_support_points;
|
||||
+ } else {
|
||||
+ /* Register 2 is TD_STATUS, containing the number of touch
|
||||
+ * points.
|
||||
+ */
|
||||
+ num_points = min(rdbuf[2] & 0xf, tsdata->max_support_points);
|
||||
+ }
|
||||
+ for (i = 0; i < num_points; i++) {
|
||||
u8 *buf = &rdbuf[i * tsdata->point_len + tsdata->tdata_offset];
|
||||
|
||||
type = buf[0] >> 6;
|
||||
@@ -335,11 +356,26 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
|
||||
|
||||
input_mt_slot(tsdata->input, id);
|
||||
if (input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER,
|
||||
- type != TOUCH_EVENT_UP))
|
||||
+ type != TOUCH_EVENT_UP)) {
|
||||
touchscreen_report_pos(tsdata->input, &tsdata->prop,
|
||||
x, y, true);
|
||||
+ active_ids |= BIT(id);
|
||||
+ } else {
|
||||
+ known_ids &= ~BIT(id);
|
||||
+ }
|
||||
}
|
||||
|
||||
+ /* One issue with the device is the TOUCH_UP message is not always
|
||||
+ * returned. Instead track which ids we know about and report when they
|
||||
+ * are no longer updated
|
||||
+ */
|
||||
+ released_ids = known_ids & ~active_ids;
|
||||
+ for_each_set_bit_from(b, &released_ids, tsdata->max_support_points) {
|
||||
+ input_mt_slot(tsdata->input, b);
|
||||
+ input_mt_report_slot_inactive(tsdata->input);
|
||||
+ }
|
||||
+ tsdata->known_ids = active_ids;
|
||||
+
|
||||
input_mt_report_pointer_emulation(tsdata->input, true);
|
||||
input_sync(tsdata->input);
|
||||
|
||||
@@ -347,6 +383,22 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+static void edt_ft5x06_ts_irq_poll_timer(struct timer_list *t)
|
||||
+{
|
||||
+ struct edt_ft5x06_ts_data *tsdata = from_timer(tsdata, t, timer);
|
||||
+
|
||||
+ schedule_work(&tsdata->work_i2c_poll);
|
||||
+ mod_timer(&tsdata->timer, jiffies + msecs_to_jiffies(POLL_INTERVAL_MS));
|
||||
+}
|
||||
+
|
||||
+static void edt_ft5x06_ts_work_i2c_poll(struct work_struct *work)
|
||||
+{
|
||||
+ struct edt_ft5x06_ts_data *tsdata = container_of(work,
|
||||
+ struct edt_ft5x06_ts_data, work_i2c_poll);
|
||||
+
|
||||
+ edt_ft5x06_ts_isr(0, tsdata);
|
||||
+}
|
||||
+
|
||||
struct edt_ft5x06_attribute {
|
||||
struct device_attribute dattr;
|
||||
size_t field_offset;
|
||||
@@ -1332,17 +1384,26 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
|
||||
return error;
|
||||
}
|
||||
|
||||
- irq_flags = irq_get_trigger_type(client->irq);
|
||||
- if (irq_flags == IRQF_TRIGGER_NONE)
|
||||
- irq_flags = IRQF_TRIGGER_FALLING;
|
||||
- irq_flags |= IRQF_ONESHOT;
|
||||
+ if (client->irq) {
|
||||
+ irq_flags = irq_get_trigger_type(client->irq);
|
||||
+ if (irq_flags == IRQF_TRIGGER_NONE)
|
||||
+ irq_flags = IRQF_TRIGGER_FALLING;
|
||||
+ irq_flags |= IRQF_ONESHOT;
|
||||
|
||||
- error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
- NULL, edt_ft5x06_ts_isr, irq_flags,
|
||||
- client->name, tsdata);
|
||||
- if (error) {
|
||||
- dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
|
||||
- return error;
|
||||
+ error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
+ NULL, edt_ft5x06_ts_isr, irq_flags,
|
||||
+ client->name, tsdata);
|
||||
+ if (error) {
|
||||
+ dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
|
||||
+ return error;
|
||||
+ }
|
||||
+ } else {
|
||||
+ INIT_WORK(&tsdata->work_i2c_poll,
|
||||
+ edt_ft5x06_ts_work_i2c_poll);
|
||||
+ timer_setup(&tsdata->timer, edt_ft5x06_ts_irq_poll_timer, 0);
|
||||
+ tsdata->timer.expires =
|
||||
+ jiffies + msecs_to_jiffies(FIRST_POLL_DELAY_MS);
|
||||
+ add_timer(&tsdata->timer);
|
||||
}
|
||||
|
||||
error = input_register_device(input);
|
||||
@@ -1364,6 +1425,10 @@ static void edt_ft5x06_ts_remove(struct i2c_client *client)
|
||||
{
|
||||
struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
|
||||
|
||||
+ if (!client->irq) {
|
||||
+ del_timer(&tsdata->timer);
|
||||
+ cancel_work_sync(&tsdata->work_i2c_poll);
|
||||
+ }
|
||||
edt_ft5x06_ts_teardown_debugfs(tsdata);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user