cregit-Linux how code gets into the kernel

Release 4.11 drivers/input/mouse/sentelic.c

/*-
 * Finger Sensing Pad PS/2 mouse driver.
 *
 * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
 * Copyright (C) 2005-2012 Tai-hwa Liang, Sentelic Corporation.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation; either version 2
 *   of the License, or (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/module.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/ctype.h>
#include <linux/libps2.h>
#include <linux/serio.h>
#include <linux/jiffies.h>
#include <linux/slab.h>

#include "psmouse.h"
#include "sentelic.h"

/*
 * Timeout for FSP PS/2 command only (in milliseconds).
 */

#define	FSP_CMD_TIMEOUT		200

#define	FSP_CMD_TIMEOUT2	30


#define	GET_ABS_X(packet)	((packet[1] << 2) | ((packet[3] >> 2) & 0x03))

#define	GET_ABS_Y(packet)	((packet[2] << 2) | (packet[3] & 0x03))

/** Driver version. */

static const char fsp_drv_ver[] = "1.1.0-K";

/*
 * Make sure that the value being sent to FSP will not conflict with
 * possible sample rate values.
 */

static unsigned char fsp_test_swap_cmd(unsigned char reg_val) { switch (reg_val) { case 10: case 20: case 40: case 60: case 80: case 100: case 200: /* * The requested value being sent to FSP matched to possible * sample rates, swap the given value such that the hardware * wouldn't get confused. */ return (reg_val >> 4) | (reg_val << 4); default: return reg_val; /* swap isn't necessary */ } }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang57100.00%1100.00%
Total57100.00%1100.00%

/* * Make sure that the value being sent to FSP will not conflict with certain * commands. */
static unsigned char fsp_test_invert_cmd(unsigned char reg_val) { switch (reg_val) { case 0xe9: case 0xee: case 0xf2: case 0xff: /* * The requested value being sent to FSP matched to certain * commands, inverse the given value such that the hardware * wouldn't get confused. */ return ~reg_val; default: return reg_val; /* inversion isn't necessary */ } }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang39100.00%1100.00%
Total39100.00%1100.00%


static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val) { struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[3]; unsigned char addr; int rc = -1; /* * We need to shut off the device and switch it into command * mode so we don't confuse our protocol handler. We don't need * to do that for writes because sysfs set helper does this for * us. */ psmouse_deactivate(psmouse); ps2_begin_command(ps2dev); if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) goto out; /* should return 0xfe(request for resending) */ ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); /* should return 0xfc(failed) */ ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) goto out; if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) { ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2); } else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) { /* swapping is required */ ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2); /* expect 0xfe */ } else { /* swapping isn't necessary */ ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); /* expect 0xfe */ } /* should return 0xfc(failed) */ ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT); if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0) goto out; *reg_val = param[2]; rc = 0; out: ps2_end_command(ps2dev); psmouse_activate(psmouse); psmouse_dbg(psmouse, "READ REG: 0x%02x is 0x%02x (rc = %d)\n", reg_addr, *reg_val, rc); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang23698.33%250.00%
Paul Fox20.83%125.00%
Dmitry Torokhov20.83%125.00%
Total240100.00%4100.00%


static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val) { struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char v; int rc = -1; ps2_begin_command(ps2dev); if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) goto out; if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) { /* inversion is required */ ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2); } else { if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) { /* swapping is required */ ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2); } else { /* swapping isn't necessary */ ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2); } } /* write the register address in correct order */ ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) goto out; if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { /* inversion is required */ ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2); } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) { /* swapping is required */ ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2); } else { /* swapping isn't necessary */ ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2); } /* write the register value in correct order */ ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); rc = 0; out: ps2_end_command(ps2dev); psmouse_dbg(psmouse, "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n", reg_addr, reg_val, rc); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang24999.20%375.00%
Dmitry Torokhov20.80%125.00%
Total251100.00%4100.00%

/* Enable register clock gating for writing certain registers */
static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable) { int v, nv; if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1) return -1; if (enable) nv = v | FSP_BIT_EN_REG_CLK; else nv = v & ~FSP_BIT_EN_REG_CLK; /* only write if necessary */ if (nv != v) if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1) return -1; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang84100.00%1100.00%
Total84100.00%1100.00%


static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val) { struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[3]; int rc = -1; psmouse_deactivate(psmouse); ps2_begin_command(ps2dev); if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) goto out; ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) goto out; ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2); ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); /* get the returned result */ if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) goto out; *reg_val = param[2]; rc = 0; out: ps2_end_command(ps2dev); psmouse_activate(psmouse); psmouse_dbg(psmouse, "READ PAGE REG: 0x%02x (rc = %d)\n", *reg_val, rc); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang16697.65%250.00%
Dmitry Torokhov21.18%125.00%
Paul Fox21.18%125.00%
Total170100.00%4100.00%


static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val) { struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char v; int rc = -1; ps2_begin_command(ps2dev); if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) goto out; ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2); ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) goto out; if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2); } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) { /* swapping is required */ ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2); } else { /* swapping isn't necessary */ ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2); } ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); rc = 0; out: ps2_end_command(ps2dev); psmouse_dbg(psmouse, "WRITE PAGE REG: to 0x%02x (rc = %d)\n", reg_val, rc); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang18498.92%375.00%
Dmitry Torokhov21.08%125.00%
Total186100.00%4100.00%


static int fsp_get_version(struct psmouse *psmouse, int *version) { if (fsp_reg_read(psmouse, FSP_REG_VERSION, version)) return -EIO; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang33100.00%1100.00%
Total33100.00%1100.00%


static int fsp_get_revision(struct psmouse *psmouse, int *rev) { if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev)) return -EIO; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang33100.00%1100.00%
Total33100.00%1100.00%


static int fsp_get_sn(struct psmouse *psmouse, int *sn) { int v0, v1, v2; int rc = -EIO; /* production number since Cx is available at: 0x0b40 ~ 0x0b42 */ if (fsp_page_reg_write(psmouse, FSP_PAGE_0B)) goto out; if (fsp_reg_read(psmouse, FSP_REG_SN0, &v0)) goto out; if (fsp_reg_read(psmouse, FSP_REG_SN1, &v1)) goto out; if (fsp_reg_read(psmouse, FSP_REG_SN2, &v2)) goto out; *sn = (v0 << 16) | (v1 << 8) | v2; rc = 0; out: fsp_page_reg_write(psmouse, FSP_PAGE_DEFAULT); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang119100.00%1100.00%
Total119100.00%1100.00%


static int fsp_get_buttons(struct psmouse *psmouse, int *btn) { static const int buttons[] = { 0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */ 0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */ 0x04, /* Left/Middle/Right & Scroll Up/Down */ 0x02, /* Left/Middle/Right */ }; int val; if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS, &val) == -1) return -EIO; *btn = buttons[(val & 0x30) >> 4]; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang75100.00%2100.00%
Total75100.00%2100.00%

/* Enable on-pad command tag output */
static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable) { int v, nv; int res = 0; if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) { psmouse_err(psmouse, "Unable get OPC state.\n"); return -EIO; } if (enable) nv = v | FSP_BIT_EN_OPC_TAG; else nv = v & ~FSP_BIT_EN_OPC_TAG; /* only write if necessary */ if (nv != v) { fsp_reg_write_enable(psmouse, true); res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv); fsp_reg_write_enable(psmouse, false); } if (res != 0) { psmouse_err(psmouse, "Unable to enable OPC tag.\n"); res = -EIO; } return res; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang127100.00%2100.00%
Total127100.00%2100.00%


static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable) { struct fsp_data *pad = psmouse->private; int val; if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val)) return -EIO; pad->vscroll = enable; if (enable) val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE); else val &= ~FSP_BIT_FIX_VSCR; if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val)) return -EIO; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang84100.00%1100.00%
Total84100.00%1100.00%


static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable) { struct fsp_data *pad = psmouse->private; int val, v2; if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val)) return -EIO; if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2)) return -EIO; pad->hscroll = enable; if (enable) { val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE); v2 |= FSP_BIT_EN_MSID6; } else { val &= ~FSP_BIT_FIX_HSCR; v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8); } if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val)) return -EIO; /* reconfigure horizontal scrolling packet output */ if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2)) return -EIO; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang137100.00%1100.00%
Total137100.00%1100.00%

/* * Write device specific initial parameters. * * ex: 0xab 0xcd - write oxcd into register 0xab */
static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data, const char *buf, size_t count) { unsigned int reg, val; char *rest; ssize_t retval; reg = simple_strtoul(buf, &rest, 16); if (rest == buf || *rest != ' ' || reg > 0xff) return -EINVAL; retval = kstrtouint(rest + 1, 16, &val); if (retval) return retval; if (val > 0xff) return -EINVAL; if (fsp_reg_write_enable(psmouse, true)) return -EIO; retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count; fsp_reg_write_enable(psmouse, false); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang12489.21%133.33%
JJ Ding139.35%133.33%
Dan Carpenter21.44%133.33%
Total139100.00%3100.00%

PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg);
static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse, void *data, char *buf) { struct fsp_data *pad = psmouse->private; return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val); }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang44100.00%1100.00%
Total44100.00%1100.00%

/* * Read a register from device. * * ex: 0xab -- read content from register 0xab */
static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data, const char *buf, size_t count) { struct fsp_data *pad = psmouse->private; unsigned int reg, val; int err; err = kstrtouint(buf, 16, &reg); if (err) return err; if (reg > 0xff) return -EINVAL; if (fsp_reg_read(psmouse, reg, &val)) return -EIO; pad->last_reg = reg; pad->last_val = val; return count; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang8281.19%133.33%
JJ Ding1514.85%133.33%
Dan Carpenter43.96%133.33%
Total101100.00%3100.00%

PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL, fsp_attr_show_getreg, fsp_attr_set_getreg);
static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse, void *data, char *buf) { int val = 0; if (fsp_page_reg_read(psmouse, &val)) return -EIO; return sprintf(buf, "%02x\n", val); }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang48100.00%1100.00%
Total48100.00%1100.00%


static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data, const char *buf, size_t count) { unsigned int val; int err; err = kstrtouint(buf, 16, &val); if (err) return err; if (val > 0xff) return -EINVAL; if (fsp_page_reg_write(psmouse, val)) return -EIO; return count; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang5776.00%133.33%
JJ Ding1418.67%133.33%
Dan Carpenter45.33%133.33%
Total75100.00%3100.00%

PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL, fsp_attr_show_pagereg, fsp_attr_set_pagereg);
static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse, void *data, char *buf) { struct fsp_data *pad = psmouse->private; return sprintf(buf, "%d\n", pad->vscroll); }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang40100.00%1100.00%
Total40100.00%1100.00%


static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count) { unsigned int val; int err; err = kstrtouint(buf, 10, &val); if (err) return err; if (val > 1) return -EINVAL; fsp_onpad_vscr(psmouse, val); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang5275.36%150.00%
JJ Ding1724.64%150.00%
Total69100.00%2100.00%

PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL, fsp_attr_show_vscroll, fsp_attr_set_vscroll);
static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse, void *data, char *buf) { struct fsp_data *pad = psmouse->private; return sprintf(buf, "%d\n", pad->hscroll); }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang40100.00%1100.00%
Total40100.00%1100.00%


static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count) { unsigned int val; int err; err = kstrtouint(buf, 10, &val); if (err) return err; if (val > 1) return -EINVAL; fsp_onpad_hscr(psmouse, val); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang5275.36%150.00%
JJ Ding1724.64%150.00%
Total69100.00%2100.00%

PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL, fsp_attr_show_hscroll, fsp_attr_set_hscroll);
static ssize_t fsp_attr_show_flags(struct psmouse *psmouse, void *data, char *buf) { struct fsp_data *pad = psmouse->private; return sprintf(buf, "%c\n", pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c'); }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang46100.00%1100.00%
Total46100.00%1100.00%


static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data, const char *buf, size_t count) { struct fsp_data *pad = psmouse->private; size_t i; for (i = 0; i < count; i++) { switch (buf[i]) { case 'C': pad->flags |= FSPDRV_FLAG_EN_OPC; break; case 'c': pad->flags &= ~FSPDRV_FLAG_EN_OPC; break; default: return -EINVAL; } } return count; }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang88100.00%1100.00%
Total88100.00%1100.00%

PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL, fsp_attr_show_flags, fsp_attr_set_flags);
static ssize_t fsp_attr_show_ver(struct psmouse *psmouse, void *data, char *buf) { return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver); }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang29100.00%1100.00%
Total29100.00%1100.00%

PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver); static struct attribute *fsp_attributes[] = { &psmouse_attr_setreg.dattr.attr, &psmouse_attr_getreg.dattr.attr, &psmouse_attr_page.dattr.attr, &psmouse_attr_vscroll.dattr.attr, &psmouse_attr_hscroll.dattr.attr, &psmouse_attr_flags.dattr.attr, &psmouse_attr_ver.dattr.attr, NULL }; static struct attribute_group fsp_attribute_group = { .attrs = fsp_attributes, }; #ifdef FSP_DEBUG
static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[]) { static unsigned int ps2_packet_cnt; static unsigned int ps2_last_second; unsigned int jiffies_msec; const char *packet_type = "UNKNOWN"; unsigned short abs_x = 0, abs_y = 0; /* Interpret & dump the packet data. */ switch (packet[0] >> FSP_PKT_TYPE_SHIFT) { case FSP_PKT_TYPE_ABS: packet_type = "Absolute"; abs_x = GET_ABS_X(packet); abs_y = GET_ABS_Y(packet); break; case FSP_PKT_TYPE_NORMAL: packet_type = "Normal"; break; case FSP_PKT_TYPE_NOTIFY: packet_type = "Notify"; break; case FSP_PKT_TYPE_NORMAL_OPC: packet_type = "Normal-OPC"; break; } ps2_packet_cnt++; jiffies_msec = jiffies_to_msecs(jiffies); psmouse_dbg(psmouse, "%08dms %s packets: %02x, %02x, %02x, %02x; " "abs_x: %d, abs_y: %d\n", jiffies_msec, packet_type, packet[0], packet[1], packet[2], packet[3], abs_x, abs_y); if (jiffies_msec - ps2_last_second > 1000) { psmouse_dbg(psmouse, "PS/2 packets/sec = %d\n", ps2_packet_cnt); ps2_packet_cnt = 0; ps2_last_second = jiffies_msec; } }

Contributors

PersonTokensPropCommitsCommitProp
Oskari Saarenmaa8849.44%133.33%
Tai-hwa Liang8447.19%133.33%
Dmitry Torokhov63.37%133.33%
Total178100.00%3100.00%

#else
static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[]) { }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang1066.67%150.00%
Oskari Saarenmaa533.33%150.00%
Total15100.00%2100.00%

#endif
static void fsp_set_slot(struct input_dev *dev, int slot, bool active, unsigned int x, unsigned int y) { input_mt_slot(dev, slot); input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); if (active) { input_report_abs(dev, ABS_MT_POSITION_X, x); input_report_abs(dev, ABS_MT_POSITION_Y, y); } }

Contributors

PersonTokensPropCommitsCommitProp
Tai-hwa Liang65100.00%1100.00%
Total65100.00%1100.00%


static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) { struct input_dev *dev