Input: sentelic - refactor code for upcoming new hardware support

- Move event bits setup code into a separate function,
  fsp_set_input_params(), so that we can perform hardware-specific settings
  in the future;
- Take hardware version information into account when activating
  protocol;
- Remove button information from boot message as it's somewhat confusing
  and is only for internal processing. While there, also move button
  retrieval code to be a part of protocol activation process.

Signed-off-by: Tai-hwa Liang <avatar@sentelic.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
Tai-hwa Liang 2012-03-25 17:15:03 -07:00 committed by Dmitry Torokhov
parent d8ee4a1c90
commit 3ac1780f9e
2 changed files with 96 additions and 64 deletions

View File

@ -128,8 +128,9 @@ static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val)
out: out:
ps2_end_command(ps2dev); ps2_end_command(ps2dev);
psmouse_activate(psmouse); psmouse_activate(psmouse);
dev_dbg(&ps2dev->serio->dev, "READ REG: 0x%02x is 0x%02x (rc = %d)\n", psmouse_dbg(psmouse,
reg_addr, *reg_val, rc); "READ REG: 0x%02x is 0x%02x (rc = %d)\n",
reg_addr, *reg_val, rc);
return rc; return rc;
} }
@ -179,8 +180,9 @@ static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val)
out: out:
ps2_end_command(ps2dev); ps2_end_command(ps2dev);
dev_dbg(&ps2dev->serio->dev, "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n", psmouse_dbg(psmouse,
reg_addr, reg_val, rc); "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n",
reg_addr, reg_val, rc);
return rc; return rc;
} }
@ -237,8 +239,9 @@ static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val)
out: out:
ps2_end_command(ps2dev); ps2_end_command(ps2dev);
psmouse_activate(psmouse); psmouse_activate(psmouse);
dev_dbg(&ps2dev->serio->dev, "READ PAGE REG: 0x%02x (rc = %d)\n", psmouse_dbg(psmouse,
*reg_val, rc); "READ PAGE REG: 0x%02x (rc = %d)\n",
*reg_val, rc);
return rc; return rc;
} }
@ -274,8 +277,9 @@ static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val)
out: out:
ps2_end_command(ps2dev); ps2_end_command(ps2dev);
dev_dbg(&ps2dev->serio->dev, "WRITE PAGE REG: to 0x%02x (rc = %d)\n", psmouse_dbg(psmouse,
reg_val, rc); "WRITE PAGE REG: to 0x%02x (rc = %d)\n",
reg_val, rc);
return rc; return rc;
} }
@ -319,7 +323,7 @@ static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
int res = 0; int res = 0;
if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) { if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) {
dev_err(&psmouse->ps2dev.serio->dev, "Unable get OPC state.\n"); psmouse_err(psmouse, "Unable get OPC state.\n");
return -EIO; return -EIO;
} }
@ -336,8 +340,7 @@ static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
} }
if (res != 0) { if (res != 0) {
dev_err(&psmouse->ps2dev.serio->dev, psmouse_err(psmouse, "Unable to enable OPC tag.\n");
"Unable to enable OPC tag.\n");
res = -EIO; res = -EIO;
} }
@ -657,8 +660,8 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
case FSP_PKT_TYPE_ABS: case FSP_PKT_TYPE_ABS:
dev_warn(&psmouse->ps2dev.serio->dev, psmouse_warn(psmouse,
"Unexpected absolute mode packet, ignored.\n"); "Unexpected absolute mode packet, ignored.\n");
break; break;
case FSP_PKT_TYPE_NORMAL_OPC: case FSP_PKT_TYPE_NORMAL_OPC:
@ -736,43 +739,70 @@ static int fsp_activate_protocol(struct psmouse *psmouse)
ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
if (param[0] != 0x04) { if (param[0] != 0x04) {
dev_err(&psmouse->ps2dev.serio->dev, psmouse_err(psmouse,
"Unable to enable 4 bytes packet format.\n"); "Unable to enable 4 bytes packet format.\n");
return -EIO; return -EIO;
} }
if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) { if (pad->ver < FSP_VER_STL3888_C0) {
dev_err(&psmouse->ps2dev.serio->dev, /* Preparing relative coordinates output for older hardware */
"Unable to read SYSCTL5 register.\n"); if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) {
return -EIO; psmouse_err(psmouse,
"Unable to read SYSCTL5 register.\n");
return -EIO;
}
if (fsp_get_buttons(psmouse, &pad->buttons)) {
psmouse_err(psmouse,
"Unable to retrieve number of buttons.\n");
return -EIO;
}
val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8);
/* Ensure we are not in absolute mode */
val &= ~FSP_BIT_EN_PKT_G0;
if (pad->buttons == 0x06) {
/* Left/Middle/Right & Scroll Up/Down/Right/Left */
val |= FSP_BIT_EN_MSID6;
}
if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) {
psmouse_err(psmouse,
"Unable to set up required mode bits.\n");
return -EIO;
}
/*
* Enable OPC tags such that driver can tell the difference
* between on-pad and real button click
*/
if (fsp_opc_tag_enable(psmouse, true))
psmouse_warn(psmouse,
"Failed to enable OPC tag mode.\n");
/* enable on-pad click by default */
pad->flags |= FSPDRV_FLAG_EN_OPC;
/* Enable on-pad vertical and horizontal scrolling */
fsp_onpad_vscr(psmouse, true);
fsp_onpad_hscr(psmouse, true);
} }
val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8); return 0;
/* Ensure we are not in absolute mode */ }
val &= ~FSP_BIT_EN_PKT_G0;
if (pad->buttons == 0x06) { static int fsp_set_input_params(struct psmouse *psmouse)
/* Left/Middle/Right & Scroll Up/Down/Right/Left */ {
val |= FSP_BIT_EN_MSID6; struct input_dev *dev = psmouse->dev;
struct fsp_data *pad = psmouse->private;
if (pad->ver < FSP_VER_STL3888_C0) {
__set_bit(BTN_MIDDLE, dev->keybit);
__set_bit(BTN_BACK, dev->keybit);
__set_bit(BTN_FORWARD, dev->keybit);
__set_bit(REL_WHEEL, dev->relbit);
__set_bit(REL_HWHEEL, dev->relbit);
} }
if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) {
dev_err(&psmouse->ps2dev.serio->dev,
"Unable to set up required mode bits.\n");
return -EIO;
}
/*
* Enable OPC tags such that driver can tell the difference between
* on-pad and real button click
*/
if (fsp_opc_tag_enable(psmouse, true))
dev_warn(&psmouse->ps2dev.serio->dev,
"Failed to enable OPC tag mode.\n");
/* Enable on-pad vertical and horizontal scrolling */
fsp_onpad_vscr(psmouse, true);
fsp_onpad_hscr(psmouse, true);
return 0; return 0;
} }
@ -829,18 +859,16 @@ static int fsp_reconnect(struct psmouse *psmouse)
int fsp_init(struct psmouse *psmouse) int fsp_init(struct psmouse *psmouse)
{ {
struct fsp_data *priv; struct fsp_data *priv;
int ver, rev, buttons; int ver, rev;
int error; int error;
if (fsp_get_version(psmouse, &ver) || if (fsp_get_version(psmouse, &ver) ||
fsp_get_revision(psmouse, &rev) || fsp_get_revision(psmouse, &rev)) {
fsp_get_buttons(psmouse, &buttons)) {
return -ENODEV; return -ENODEV;
} }
psmouse_info(psmouse, psmouse_info(psmouse, "Finger Sensing Pad, hw: %d.%d.%d, sw: %s\n",
"Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n", ver >> 4, ver & 0x0F, rev, fsp_drv_ver);
ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7);
psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL);
if (!priv) if (!priv)
@ -848,17 +876,6 @@ int fsp_init(struct psmouse *psmouse)
priv->ver = ver; priv->ver = ver;
priv->rev = rev; priv->rev = rev;
priv->buttons = buttons;
/* enable on-pad click by default */
priv->flags |= FSPDRV_FLAG_EN_OPC;
/* Set up various supported input event bits */
__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
__set_bit(BTN_BACK, psmouse->dev->keybit);
__set_bit(BTN_FORWARD, psmouse->dev->keybit);
__set_bit(REL_WHEEL, psmouse->dev->relbit);
__set_bit(REL_HWHEEL, psmouse->dev->relbit);
psmouse->protocol_handler = fsp_process_byte; psmouse->protocol_handler = fsp_process_byte;
psmouse->disconnect = fsp_disconnect; psmouse->disconnect = fsp_disconnect;
@ -866,16 +883,20 @@ int fsp_init(struct psmouse *psmouse)
psmouse->cleanup = fsp_reset; psmouse->cleanup = fsp_reset;
psmouse->pktsize = 4; psmouse->pktsize = 4;
/* set default packet output based on number of buttons we found */
error = fsp_activate_protocol(psmouse); error = fsp_activate_protocol(psmouse);
if (error) if (error)
goto err_out; goto err_out;
/* Set up various supported input event bits */
error = fsp_set_input_params(psmouse);
if (error)
goto err_out;
error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
&fsp_attribute_group); &fsp_attribute_group);
if (error) { if (error) {
dev_err(&psmouse->ps2dev.serio->dev, psmouse_err(psmouse,
"Failed to create sysfs attributes (%d)", error); "Failed to create sysfs attributes (%d)", error);
goto err_out; goto err_out;
} }

View File

@ -64,12 +64,23 @@
#define FSP_PKT_TYPE_NORMAL_OPC (0x03) #define FSP_PKT_TYPE_NORMAL_OPC (0x03)
#define FSP_PKT_TYPE_SHIFT (6) #define FSP_PKT_TYPE_SHIFT (6)
/* hardware revisions */
#define FSP_VER_STL3888_A4 (0xC1)
#define FSP_VER_STL3888_B0 (0xD0)
#define FSP_VER_STL3888_B1 (0xD1)
#define FSP_VER_STL3888_B2 (0xD2)
#define FSP_VER_STL3888_C0 (0xE0)
#define FSP_VER_STL3888_C1 (0xE1)
#define FSP_VER_STL3888_D0 (0xE2)
#define FSP_VER_STL3888_D1 (0xE3)
#define FSP_VER_STL3888_E0 (0xE4)
#ifdef __KERNEL__ #ifdef __KERNEL__
struct fsp_data { struct fsp_data {
unsigned char ver; /* hardware version */ unsigned char ver; /* hardware version */
unsigned char rev; /* hardware revison */ unsigned char rev; /* hardware revison */
unsigned char buttons; /* Number of buttons */ unsigned int buttons; /* Number of buttons */
unsigned int flags; unsigned int flags;
#define FSPDRV_FLAG_EN_OPC (0x001) /* enable on-pad clicking */ #define FSPDRV_FLAG_EN_OPC (0x001) /* enable on-pad clicking */