stmfts: update touch handling
This commit is contained in:
1 parent
3e090e8a5a
commit
08bd2cf2fd
1 file changed
+282
-86
@@ -66,6 +66,7 @@
|
||||
#define STMFTS_EV_SLEEP_OUT_CONTROLLER_READY 0x11
|
||||
#define STMFTS_EV_STATUS 0x16
|
||||
#define STMFTS_EV_DEBUG 0xdb
|
||||
#define STMFTM4_PRESSURE_MAX 500
|
||||
|
||||
/* FTM4 done status */
|
||||
#define STMFTM4_STATUS_MS_CX_TUNING_DONE 0x01
|
||||
@@ -148,11 +149,22 @@ struct stmfts_data {
|
||||
bool hover_enabled;
|
||||
bool stylus_enabled;
|
||||
bool running;
|
||||
unsigned int touch_count;
|
||||
unsigned int n_events;
|
||||
bool palm_pressed;
|
||||
u8 palm_id;
|
||||
u8 finger_state[STMFTS_MAX_FINGERS];
|
||||
bool coord_factor;
|
||||
u32 x_real_max;
|
||||
u32 y_real_max;
|
||||
u32 x_edge;
|
||||
u32 y_edge;
|
||||
};
|
||||
|
||||
struct stmfts_chip_ops {
|
||||
int (*configure)(struct stmfts_data *sdata);
|
||||
int (*setup_input)(struct stmfts_data *sdata);
|
||||
int (*read_events)(struct stmfts_data *sdata);
|
||||
void (*parse_events)(struct stmfts_data *sdata);
|
||||
int (*set_scan)(struct stmfts_data *sdata, bool enable);
|
||||
int (*set_hover)(struct stmfts_data *sdata, bool enable);
|
||||
@@ -223,48 +235,47 @@ static int stmfts_read_events(struct stmfts_data *sdata)
|
||||
return ret == ARRAY_SIZE(msgs) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static int ftm4_write_reg(struct stmfts_data *sdata, unsigned char *reg,
|
||||
unsigned short num_com)
|
||||
static int ftm4_write_reg(struct stmfts_data *sdata, u8 *reg, unsigned int len)
|
||||
{
|
||||
struct i2c_msg xfer_msg[1] = {
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = sdata->client->addr,
|
||||
.len = num_com,
|
||||
.len = len,
|
||||
.buf = reg,
|
||||
},
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = i2c_transfer(sdata->client->adapter, xfer_msg, 1);
|
||||
ret = i2c_transfer(sdata->client->adapter, msgs, ARRAY_SIZE(msgs));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret == 1 ? 0 : -EIO;
|
||||
return ret == ARRAY_SIZE(msgs) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static int ftm4_read_reg(struct stmfts_data *sdata, unsigned char *reg,
|
||||
int cnum, unsigned char *buf, int num)
|
||||
static int ftm4_read_reg(struct stmfts_data *sdata, u8 *reg, unsigned int wlen,
|
||||
u8 *buf, unsigned int rlen)
|
||||
{
|
||||
struct i2c_msg xfer_msg[2] = {
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = sdata->client->addr,
|
||||
.len = cnum,
|
||||
.len = wlen,
|
||||
.buf = reg,
|
||||
},
|
||||
{
|
||||
.addr = sdata->client->addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = num,
|
||||
.len = rlen,
|
||||
.buf = buf,
|
||||
},
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = i2c_transfer(sdata->client->adapter, xfer_msg, 2);
|
||||
ret = i2c_transfer(sdata->client->adapter, msgs, ARRAY_SIZE(msgs));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret == 2 ? 0 : -EIO;
|
||||
return ret == ARRAY_SIZE(msgs) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
/* FTS4 event handling functions */
|
||||
@@ -387,70 +398,6 @@ static void stmfts5_report_contact_release(struct stmfts_data *sdata,
|
||||
input_mt_report_slot_inactive(sdata->input);
|
||||
}
|
||||
|
||||
/* FTM4 event handling functions */
|
||||
static void stmftm4_report_contact_event(struct stmfts_data *sdata,
|
||||
const u8 event[])
|
||||
{
|
||||
u8 slot = event[0] >> 4;
|
||||
u16 x = (event[1] << 4) | (event[3] >> 4);
|
||||
u16 y = (event[2] << 4) | (event[3] & 0x0f);
|
||||
unsigned int gain = event[6] & 0x3f;
|
||||
unsigned int z = (event[4] | (event[5] << 8)) << 6;
|
||||
unsigned int orient = ((event[7] & 0x80) >> 5) | (event[6] >> 6);
|
||||
|
||||
if (gain == 0 || gain == 0x3f)
|
||||
gain = 0x40;
|
||||
z /= gain + 0x40;
|
||||
|
||||
input_mt_slot(sdata->input, slot);
|
||||
input_mt_report_slot_state(sdata->input, MT_TOOL_FINGER, true);
|
||||
input_report_abs(sdata->input, ABS_MT_POSITION_X, x);
|
||||
input_report_abs(sdata->input, ABS_MT_POSITION_Y, y);
|
||||
input_report_abs(sdata->input, ABS_MT_PRESSURE, z);
|
||||
input_report_abs(sdata->input, ABS_MT_ORIENTATION, orient);
|
||||
}
|
||||
|
||||
static void stmftm4_parse_events(struct stmfts_data *sdata)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < STMFTS_STACK_DEPTH; i++) {
|
||||
u8 *event = &sdata->data[i * STMFTS_EVENT_SIZE];
|
||||
|
||||
switch (event[0]) {
|
||||
case STMFTS_EV_CONTROLLER_READY:
|
||||
case STMFTS_EV_STATUS:
|
||||
complete(&sdata->cmd_done);
|
||||
fallthrough;
|
||||
case STMFTS_EV_NO_EVENT:
|
||||
case STMFTS_EV_DEBUG:
|
||||
goto sync;
|
||||
}
|
||||
|
||||
switch (event[0] & STMFTS_MASK_EVENT_ID) {
|
||||
case STMFTS_EV_MULTI_TOUCH_ENTER:
|
||||
case STMFTS_EV_MULTI_TOUCH_MOTION:
|
||||
stmftm4_report_contact_event(sdata, event);
|
||||
break;
|
||||
case STMFTS_EV_MULTI_TOUCH_LEAVE:
|
||||
stmfts_report_contact_release(sdata, event);
|
||||
break;
|
||||
case STMFTS_EV_ERROR:
|
||||
dev_warn(&sdata->client->dev,
|
||||
"error code: %02x %02x %02x\n",
|
||||
event[0], event[1], event[2]);
|
||||
break;
|
||||
default:
|
||||
dev_err(&sdata->client->dev,
|
||||
"unknown event %#02x\n", event[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sync:
|
||||
input_sync(sdata->input);
|
||||
}
|
||||
|
||||
static void stmfts_report_hover_event(struct stmfts_data *sdata,
|
||||
const u8 event[])
|
||||
{
|
||||
@@ -464,6 +411,219 @@ static void stmfts_report_hover_event(struct stmfts_data *sdata,
|
||||
input_sync(sdata->input);
|
||||
}
|
||||
|
||||
static void stmftm4_release_all(struct stmfts_data *sdata)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < STMFTS_MAX_FINGERS; i++) {
|
||||
input_mt_slot(sdata->input, i);
|
||||
input_mt_report_slot_inactive(sdata->input);
|
||||
sdata->finger_state[i] = STMFTS_EV_MULTI_TOUCH_LEAVE;
|
||||
}
|
||||
sdata->touch_count = 0;
|
||||
input_report_key(sdata->input, BTN_TOUCH, 0);
|
||||
input_report_key(sdata->input, BTN_TOOL_FINGER, 0);
|
||||
}
|
||||
|
||||
static void stmftm4_factor_coords(struct stmfts_data *sdata, int *x, int *y)
|
||||
{
|
||||
unsigned int x_work = max_t(unsigned int, *x, sdata->x_edge);
|
||||
unsigned int y_work = max_t(unsigned int, *y, sdata->y_edge);
|
||||
unsigned int x_span = sdata->x_real_max - sdata->x_edge;
|
||||
unsigned int y_span = sdata->y_real_max - sdata->y_edge;
|
||||
unsigned int x_max = input_abs_get_max(sdata->input, ABS_MT_POSITION_X);
|
||||
unsigned int y_max = input_abs_get_max(sdata->input, ABS_MT_POSITION_Y);
|
||||
|
||||
if (!x_span || !y_span)
|
||||
return;
|
||||
|
||||
x_work = min(x_work, sdata->x_real_max) - sdata->x_edge;
|
||||
y_work = min(y_work, sdata->y_real_max) - sdata->y_edge;
|
||||
*x = x_work * (x_max * 1000 / x_span) / 1000;
|
||||
*y = y_work * (y_max * 1000 / y_span) / 1000;
|
||||
}
|
||||
|
||||
static int stmftm4_orientation(const u8 event[])
|
||||
{
|
||||
unsigned int code = ((event[7] & 0x80) >> 5) | (event[6] >> 6);
|
||||
|
||||
switch (code) {
|
||||
case 1: return 45000;
|
||||
case 2: return 90000;
|
||||
case 3: return -45000;
|
||||
case 4: return 22500;
|
||||
case 5: return 67500;
|
||||
case 6: return -22500;
|
||||
case 7: return -67500;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void stmftm4_report_contact_event(struct stmfts_data *sdata,
|
||||
const u8 event[], u8 slot, u8 id)
|
||||
{
|
||||
int x = (event[1] << 4) | (event[3] >> 4);
|
||||
int y = (event[2] << 4) | (event[3] & 0x0f);
|
||||
unsigned int gain = event[6] & 0x3f;
|
||||
unsigned int z = (event[4] | (event[5] << 8)) << 6;
|
||||
|
||||
if (gain == 0 || gain == 0x3f)
|
||||
gain = 0x40;
|
||||
z /= gain + 0x40;
|
||||
|
||||
if (z > STMFTM4_PRESSURE_MAX) {
|
||||
dev_info(&sdata->client->dev, "palm detected on slot %u\n", slot);
|
||||
stmftm4_release_all(sdata);
|
||||
sdata->palm_id = slot;
|
||||
sdata->palm_pressed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sdata->coord_factor)
|
||||
stmftm4_factor_coords(sdata, &x, &y);
|
||||
|
||||
input_mt_slot(sdata->input, slot);
|
||||
input_mt_report_slot_state(sdata->input, MT_TOOL_FINGER, true);
|
||||
touchscreen_report_pos(sdata->input, &sdata->prop, x, y, true);
|
||||
input_report_abs(sdata->input, ABS_MT_PRESSURE, z);
|
||||
input_report_abs(sdata->input, ABS_MT_TOUCH_MAJOR, 48);
|
||||
input_report_abs(sdata->input, ABS_MT_TOUCH_MINOR, 48);
|
||||
input_report_abs(sdata->input, ABS_MT_ORIENTATION,
|
||||
stmftm4_orientation(event));
|
||||
input_report_key(sdata->input, BTN_TOUCH, 1);
|
||||
input_report_key(sdata->input, BTN_TOOL_FINGER, 1);
|
||||
sdata->finger_state[slot] = id;
|
||||
}
|
||||
|
||||
static void stmftm4_report_release(struct stmfts_data *sdata, u8 slot)
|
||||
{
|
||||
if (slot >= STMFTS_MAX_FINGERS)
|
||||
return;
|
||||
|
||||
input_mt_slot(sdata->input, slot);
|
||||
input_mt_report_slot_inactive(sdata->input);
|
||||
sdata->finger_state[slot] = STMFTS_EV_MULTI_TOUCH_LEAVE;
|
||||
if (sdata->touch_count)
|
||||
sdata->touch_count--;
|
||||
if (!sdata->touch_count) {
|
||||
input_report_key(sdata->input, BTN_TOUCH, 0);
|
||||
input_report_key(sdata->input, BTN_TOOL_FINGER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int stmftm4_read_events(struct stmfts_data *sdata)
|
||||
{
|
||||
u8 count_reg[3] = { STMFTS_WRITE_REG, 0x00, 0x23 };
|
||||
u8 raw[2] = { };
|
||||
u8 cmd = STMFTS_READ_ALL_EVENT;
|
||||
unsigned int count;
|
||||
int ret;
|
||||
|
||||
ret = ftm4_read_reg(sdata, count_reg, sizeof(count_reg), raw, sizeof(raw));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Old driver shifts the little-endian short, leaving the second byte. */
|
||||
count = raw[1] / 2;
|
||||
if (count > STMFTS_STACK_DEPTH)
|
||||
count = STMFTS_STACK_DEPTH;
|
||||
sdata->n_events = count;
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
memset(sdata->data, 0, count * STMFTS_EVENT_SIZE);
|
||||
return ftm4_read_reg(sdata, &cmd, 1, sdata->data,
|
||||
count * STMFTS_EVENT_SIZE);
|
||||
}
|
||||
|
||||
static void stmftm4_parse_events(struct stmfts_data *sdata)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < sdata->n_events; i++) {
|
||||
u8 *event = &sdata->data[i * STMFTS_EVENT_SIZE];
|
||||
u8 id = event[0] & STMFTS_MASK_EVENT_ID;
|
||||
u8 slot = event[0] >> 4;
|
||||
|
||||
if (id < STMFTS_EV_MULTI_TOUCH_ENTER ||
|
||||
id > STMFTS_EV_MULTI_TOUCH_MOTION) {
|
||||
id = event[0];
|
||||
slot = event[1] & 0x0f;
|
||||
}
|
||||
if (slot >= STMFTS_MAX_FINGERS &&
|
||||
(id == STMFTS_EV_MULTI_TOUCH_ENTER ||
|
||||
id == STMFTS_EV_MULTI_TOUCH_MOTION ||
|
||||
id == STMFTS_EV_MULTI_TOUCH_LEAVE ||
|
||||
id == STMFTS_EV_HOVER_LEAVE))
|
||||
continue;
|
||||
|
||||
switch (id) {
|
||||
case STMFTS_EV_NO_EVENT:
|
||||
break;
|
||||
case STMFTS_EV_ERROR:
|
||||
if (event[1] == 0x08)
|
||||
dev_err(&sdata->client->dev,
|
||||
"auto tune failed: %02x\n", event[2]);
|
||||
else if (event[1] == 0x09)
|
||||
dev_err(&sdata->client->dev, "sync detect failed\n");
|
||||
else
|
||||
dev_warn(&sdata->client->dev,
|
||||
"error code: %02x %02x %02x\n",
|
||||
event[0], event[1], event[2]);
|
||||
break;
|
||||
case STMFTS_EV_HOVER_ENTER:
|
||||
case STMFTS_EV_HOVER_MOTION:
|
||||
break;
|
||||
case STMFTS_EV_HOVER_LEAVE:
|
||||
stmftm4_report_release(sdata, slot);
|
||||
break;
|
||||
case STMFTS_EV_MULTI_TOUCH_ENTER:
|
||||
sdata->touch_count++;
|
||||
fallthrough;
|
||||
case STMFTS_EV_MULTI_TOUCH_MOTION:
|
||||
if (!sdata->touch_count) {
|
||||
stmftm4_release_all(sdata);
|
||||
break;
|
||||
}
|
||||
if (id == STMFTS_EV_MULTI_TOUCH_MOTION &&
|
||||
sdata->finger_state[slot] == STMFTS_EV_MULTI_TOUCH_LEAVE)
|
||||
break;
|
||||
if (sdata->palm_pressed)
|
||||
break;
|
||||
stmftm4_report_contact_event(sdata, event, slot, id);
|
||||
break;
|
||||
case STMFTS_EV_MULTI_TOUCH_LEAVE:
|
||||
if (sdata->palm_pressed) {
|
||||
if (sdata->palm_id == slot) {
|
||||
stmftm4_release_all(sdata);
|
||||
sdata->palm_pressed = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!sdata->touch_count) {
|
||||
stmftm4_release_all(sdata);
|
||||
break;
|
||||
}
|
||||
stmftm4_report_release(sdata, slot);
|
||||
break;
|
||||
case STMFTS_EV_CONTROLLER_READY:
|
||||
case STMFTS_EV_STATUS:
|
||||
complete(&sdata->cmd_done);
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&sdata->client->dev,
|
||||
"event %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
event[0], event[1], event[2], event[3],
|
||||
event[4], event[5], event[6], event[7]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
input_mt_sync_frame(sdata->input);
|
||||
input_sync(sdata->input);
|
||||
sdata->n_events = 0;
|
||||
}
|
||||
|
||||
static void stmfts_report_key_event(struct stmfts_data *sdata, const u8 event[])
|
||||
{
|
||||
switch (event[2]) {
|
||||
@@ -582,7 +742,7 @@ static irqreturn_t stmfts_irq_handler(int irq, void *dev)
|
||||
|
||||
guard(mutex)(&sdata->mutex);
|
||||
|
||||
err = stmfts_read_events(sdata);
|
||||
err = sdata->ops->read_events(sdata);
|
||||
if (unlikely(err))
|
||||
dev_err(&sdata->client->dev,
|
||||
"failed to read events: %d\n", err);
|
||||
@@ -832,6 +992,7 @@ static int stmfts_read_system_info(struct stmfts_data *sdata)
|
||||
sizeof(reg), reg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (err != sizeof(reg))
|
||||
return -EIO;
|
||||
|
||||
@@ -863,7 +1024,7 @@ static int stmftm4_read_system_info(struct stmfts_data *sdata)
|
||||
sdata->config_id = 0;
|
||||
sdata->config_ver = 0;
|
||||
|
||||
dev_info(&sdata->client->dev, "FTM4: chip_id: %04x fw_ver: %04x\n",
|
||||
dev_info(&sdata->client->dev, "chip_id: %04x fw_ver: %04x\n",
|
||||
sdata->chip_id, sdata->fw_ver);
|
||||
|
||||
return 0;
|
||||
@@ -965,6 +1126,7 @@ static int stmfts_configure(struct stmfts_data *sdata)
|
||||
dev_warn(&sdata->client->dev,
|
||||
"failed to perform self auto tune: %d\n", err);
|
||||
|
||||
dev_info(&sdata->client->dev, "calib\n");
|
||||
err = stmfts_command(sdata, STMFTS_FULL_FORCE_CALIBRATION);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -990,10 +1152,11 @@ static int stmftm4_configure(struct stmfts_data *sdata)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Trim low power oscillator */
|
||||
/* Trim low power oscillator. No completion event. */
|
||||
stmftm4_command(sdata, STMFTS_TRIM_LOW_POWER_OSCILLATOR);
|
||||
msleep(200);
|
||||
|
||||
dev_info(&sdata->client->dev, "ms tuning\n");
|
||||
err = stmftm4_command(sdata, STMFTS_MS_CX_TUNING);
|
||||
if (!err)
|
||||
err = stmftm4_wait_status(sdata, STMFTM4_STATUS_MS_CX_TUNING_DONE);
|
||||
@@ -1001,6 +1164,7 @@ static int stmftm4_configure(struct stmfts_data *sdata)
|
||||
dev_warn(&sdata->client->dev,
|
||||
"failed to perform mutual auto tune: %d\n", err);
|
||||
|
||||
dev_info(&sdata->client->dev, "cx tuning\n");
|
||||
err = stmftm4_command(sdata, STMFTS_SS_CX_TUNING);
|
||||
if (!err)
|
||||
err = stmftm4_wait_status(sdata, STMFTM4_STATUS_SS_CX_TUNING_DONE);
|
||||
@@ -1136,10 +1300,8 @@ static void stmfts_power_off(void *data)
|
||||
struct stmfts_data *sdata = data;
|
||||
|
||||
disable_irq(sdata->client->irq);
|
||||
|
||||
if (sdata->reset_gpio)
|
||||
gpiod_set_value_cansleep(sdata->reset_gpio, 1);
|
||||
|
||||
regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies), sdata->supplies);
|
||||
}
|
||||
|
||||
@@ -1162,6 +1324,38 @@ static int stmfts_setup_input(struct stmfts_data *sdata)
|
||||
INPUT_MT_DIRECT);
|
||||
}
|
||||
|
||||
static int stmftm4_setup_input(struct stmfts_data *sdata)
|
||||
{
|
||||
struct device *dev = &sdata->client->dev;
|
||||
u32 coords[2];
|
||||
unsigned int i;
|
||||
|
||||
input_set_capability(sdata->input, EV_KEY, BTN_TOUCH);
|
||||
input_set_capability(sdata->input, EV_KEY, BTN_TOOL_FINGER);
|
||||
input_set_abs_params(sdata->input, ABS_MT_PRESSURE, 0,
|
||||
STMFTM4_PRESSURE_MAX, 0, 0);
|
||||
input_set_abs_params(sdata->input, ABS_MT_ORIENTATION,
|
||||
-67500, 90000, 0, 0);
|
||||
|
||||
for (i = 0; i < STMFTS_MAX_FINGERS; i++)
|
||||
sdata->finger_state[i] = STMFTS_EV_MULTI_TOUCH_LEAVE;
|
||||
|
||||
if (!device_property_read_u32_array(dev, "st,max-real-coords",
|
||||
coords, 2)) {
|
||||
sdata->coord_factor = true;
|
||||
sdata->x_real_max = coords[0];
|
||||
sdata->y_real_max = coords[1];
|
||||
if (!device_property_read_u32_array(dev, "st,edge-offset",
|
||||
coords, 2)) {
|
||||
sdata->x_edge = coords[0];
|
||||
sdata->y_edge = coords[1];
|
||||
}
|
||||
}
|
||||
|
||||
return input_mt_init_slots(sdata->input, STMFTS_MAX_FINGERS,
|
||||
INPUT_MT_DIRECT);
|
||||
}
|
||||
|
||||
static int stmfts5_setup_input(struct stmfts_data *sdata)
|
||||
{
|
||||
struct device *dev = &sdata->client->dev;
|
||||
@@ -1231,7 +1425,6 @@ static int stmfts_probe(struct i2c_client *client)
|
||||
sdata->client = client;
|
||||
mutex_init(&sdata->mutex);
|
||||
init_completion(&sdata->cmd_done);
|
||||
|
||||
sdata->ops = i2c_get_match_data(client);
|
||||
|
||||
err = devm_regulator_bulk_get_const(dev,
|
||||
@@ -1366,11 +1559,13 @@ static int stmfts5_chip_runtime_resume(struct stmfts_data *sdata)
|
||||
err = i2c_smbus_write_byte(client, STMFTS_MS_CX_TUNING);
|
||||
if (err)
|
||||
dev_warn(dev, "MS_CX_TUNING failed: %d\n", err);
|
||||
|
||||
msleep(20);
|
||||
|
||||
err = i2c_smbus_write_byte(client, STMFTS_SS_CX_TUNING);
|
||||
if (err)
|
||||
dev_warn(dev, "SS_CX_TUNING failed: %d\n", err);
|
||||
|
||||
msleep(20);
|
||||
|
||||
/* Force calibration */
|
||||
@@ -1426,6 +1621,7 @@ static const struct dev_pm_ops stmfts_pm_ops = {
|
||||
static const struct stmfts_chip_ops stmfts4_ops = {
|
||||
.configure = stmfts_configure,
|
||||
.setup_input = stmfts_setup_input,
|
||||
.read_events = stmfts_read_events,
|
||||
.parse_events = stmfts_parse_events,
|
||||
.set_scan = stmfts_set_scan,
|
||||
.set_hover = stmfts_set_hover,
|
||||
@@ -1437,6 +1633,7 @@ static const struct stmfts_chip_ops stmfts4_ops = {
|
||||
static const struct stmfts_chip_ops stmfts5_ops = {
|
||||
.configure = stmfts5_configure,
|
||||
.setup_input = stmfts5_setup_input,
|
||||
.read_events = stmfts_read_events,
|
||||
.parse_events = stmfts5_parse_events,
|
||||
.set_scan = stmfts5_set_scan,
|
||||
.power_on = stmfts_chip_power_on,
|
||||
@@ -1446,10 +1643,10 @@ static const struct stmfts_chip_ops stmfts5_ops = {
|
||||
|
||||
static const struct stmfts_chip_ops stmftm4_ops = {
|
||||
.configure = stmftm4_configure,
|
||||
.setup_input = stmfts_setup_input,
|
||||
.setup_input = stmftm4_setup_input,
|
||||
.read_events = stmftm4_read_events,
|
||||
.parse_events = stmftm4_parse_events,
|
||||
.set_scan = stmfts_set_scan,
|
||||
.set_hover = stmfts_set_hover,
|
||||
.power_on = stmftm4_power_on,
|
||||
.runtime_suspend = stmftm4_runtime_suspend,
|
||||
.runtime_resume = stmftm4_configure,
|
||||
@@ -1485,7 +1682,6 @@ static struct i2c_driver stmfts_driver = {
|
||||
.remove = stmfts_remove,
|
||||
.id_table = stmfts_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(stmfts_driver);
|
||||
|
||||
MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>");
|
||||
|
||||
Reference in new issue
Block a user