0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/device.h>
0015 #include <linux/libps2.h>
0016 #include <linux/input/mt.h>
0017 #include <linux/serio.h>
0018 #include <linux/slab.h>
0019 #include "psmouse.h"
0020 #include "focaltech.h"
0021
0022 static const char * const focaltech_pnp_ids[] = {
0023 "FLT0101",
0024 "FLT0102",
0025 "FLT0103",
0026 NULL
0027 };
0028
0029
0030
0031
0032
0033
0034
0035 int focaltech_detect(struct psmouse *psmouse, bool set_properties)
0036 {
0037 if (!psmouse_matches_pnp_id(psmouse, focaltech_pnp_ids))
0038 return -ENODEV;
0039
0040 if (set_properties) {
0041 psmouse->vendor = "FocalTech";
0042 psmouse->name = "Touchpad";
0043 }
0044
0045 return 0;
0046 }
0047
0048 #ifdef CONFIG_MOUSE_PS2_FOCALTECH
0049
0050
0051
0052
0053
0054 #define FOC_TOUCH 0x3
0055 #define FOC_ABS 0x6
0056 #define FOC_REL 0x9
0057
0058 #define FOC_MAX_FINGERS 5
0059
0060
0061
0062
0063 struct focaltech_finger_state {
0064
0065 bool active;
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 bool valid;
0076
0077
0078
0079
0080
0081 unsigned int x;
0082 unsigned int y;
0083 };
0084
0085
0086
0087
0088 struct focaltech_hw_state {
0089
0090
0091
0092
0093
0094 struct focaltech_finger_state fingers[FOC_MAX_FINGERS];
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 unsigned int width;
0105
0106
0107 bool pressed;
0108 };
0109
0110 struct focaltech_data {
0111 unsigned int x_max, y_max;
0112 struct focaltech_hw_state state;
0113 };
0114
0115 static void focaltech_report_state(struct psmouse *psmouse)
0116 {
0117 struct focaltech_data *priv = psmouse->private;
0118 struct focaltech_hw_state *state = &priv->state;
0119 struct input_dev *dev = psmouse->dev;
0120 int i;
0121
0122 for (i = 0; i < FOC_MAX_FINGERS; i++) {
0123 struct focaltech_finger_state *finger = &state->fingers[i];
0124 bool active = finger->active && finger->valid;
0125
0126 input_mt_slot(dev, i);
0127 input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
0128 if (active) {
0129 unsigned int clamped_x, clamped_y;
0130
0131
0132
0133
0134
0135 clamped_x = clamp(finger->x, 0U, priv->x_max);
0136 clamped_y = clamp(finger->y, 0U, priv->y_max);
0137 input_report_abs(dev, ABS_MT_POSITION_X, clamped_x);
0138 input_report_abs(dev, ABS_MT_POSITION_Y,
0139 priv->y_max - clamped_y);
0140 input_report_abs(dev, ABS_TOOL_WIDTH, state->width);
0141 }
0142 }
0143 input_mt_report_pointer_emulation(dev, true);
0144
0145 input_report_key(dev, BTN_LEFT, state->pressed);
0146 input_sync(dev);
0147 }
0148
0149 static void focaltech_process_touch_packet(struct psmouse *psmouse,
0150 unsigned char *packet)
0151 {
0152 struct focaltech_data *priv = psmouse->private;
0153 struct focaltech_hw_state *state = &priv->state;
0154 unsigned char fingers = packet[1];
0155 int i;
0156
0157 state->pressed = (packet[0] >> 4) & 1;
0158
0159
0160 for (i = 0; i < FOC_MAX_FINGERS; i++) {
0161 state->fingers[i].active = fingers & 0x1;
0162 if (!state->fingers[i].active) {
0163
0164
0165
0166
0167 state->fingers[i].valid = false;
0168 }
0169 fingers >>= 1;
0170 }
0171 }
0172
0173 static void focaltech_process_abs_packet(struct psmouse *psmouse,
0174 unsigned char *packet)
0175 {
0176 struct focaltech_data *priv = psmouse->private;
0177 struct focaltech_hw_state *state = &priv->state;
0178 unsigned int finger;
0179
0180 finger = (packet[1] >> 4) - 1;
0181 if (finger >= FOC_MAX_FINGERS) {
0182 psmouse_err(psmouse, "Invalid finger in abs packet: %d\n",
0183 finger);
0184 return;
0185 }
0186
0187 state->pressed = (packet[0] >> 4) & 1;
0188
0189 state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2];
0190 state->fingers[finger].y = (packet[3] << 8) | packet[4];
0191 state->width = packet[5] >> 4;
0192 state->fingers[finger].valid = true;
0193 }
0194
0195 static void focaltech_process_rel_packet(struct psmouse *psmouse,
0196 unsigned char *packet)
0197 {
0198 struct focaltech_data *priv = psmouse->private;
0199 struct focaltech_hw_state *state = &priv->state;
0200 int finger1, finger2;
0201
0202 state->pressed = packet[0] >> 7;
0203 finger1 = ((packet[0] >> 4) & 0x7) - 1;
0204 if (finger1 < FOC_MAX_FINGERS) {
0205 state->fingers[finger1].x += (char)packet[1];
0206 state->fingers[finger1].y += (char)packet[2];
0207 } else {
0208 psmouse_err(psmouse, "First finger in rel packet invalid: %d\n",
0209 finger1);
0210 }
0211
0212
0213
0214
0215
0216
0217
0218
0219 finger2 = ((packet[3] >> 4) & 0x7) - 1;
0220 if (finger2 < FOC_MAX_FINGERS) {
0221 state->fingers[finger2].x += (char)packet[4];
0222 state->fingers[finger2].y += (char)packet[5];
0223 }
0224 }
0225
0226 static void focaltech_process_packet(struct psmouse *psmouse)
0227 {
0228 unsigned char *packet = psmouse->packet;
0229
0230 switch (packet[0] & 0xf) {
0231 case FOC_TOUCH:
0232 focaltech_process_touch_packet(psmouse, packet);
0233 break;
0234
0235 case FOC_ABS:
0236 focaltech_process_abs_packet(psmouse, packet);
0237 break;
0238
0239 case FOC_REL:
0240 focaltech_process_rel_packet(psmouse, packet);
0241 break;
0242
0243 default:
0244 psmouse_err(psmouse, "Unknown packet type: %02x\n", packet[0]);
0245 break;
0246 }
0247
0248 focaltech_report_state(psmouse);
0249 }
0250
0251 static psmouse_ret_t focaltech_process_byte(struct psmouse *psmouse)
0252 {
0253 if (psmouse->pktcnt >= 6) {
0254 focaltech_process_packet(psmouse);
0255 return PSMOUSE_FULL_PACKET;
0256 }
0257
0258
0259
0260
0261
0262 return PSMOUSE_GOOD_DATA;
0263 }
0264
0265 static int focaltech_switch_protocol(struct psmouse *psmouse)
0266 {
0267 struct ps2dev *ps2dev = &psmouse->ps2dev;
0268 unsigned char param[3];
0269
0270 param[0] = 0;
0271 if (ps2_command(ps2dev, param, 0x10f8))
0272 return -EIO;
0273
0274 if (ps2_command(ps2dev, param, 0x10f8))
0275 return -EIO;
0276
0277 if (ps2_command(ps2dev, param, 0x10f8))
0278 return -EIO;
0279
0280 param[0] = 1;
0281 if (ps2_command(ps2dev, param, 0x10f8))
0282 return -EIO;
0283
0284 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11))
0285 return -EIO;
0286
0287 if (ps2_command(ps2dev, param, PSMOUSE_CMD_ENABLE))
0288 return -EIO;
0289
0290 return 0;
0291 }
0292
0293 static void focaltech_reset(struct psmouse *psmouse)
0294 {
0295 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
0296 psmouse_reset(psmouse);
0297 }
0298
0299 static void focaltech_disconnect(struct psmouse *psmouse)
0300 {
0301 focaltech_reset(psmouse);
0302 kfree(psmouse->private);
0303 psmouse->private = NULL;
0304 }
0305
0306 static int focaltech_reconnect(struct psmouse *psmouse)
0307 {
0308 int error;
0309
0310 focaltech_reset(psmouse);
0311
0312 error = focaltech_switch_protocol(psmouse);
0313 if (error) {
0314 psmouse_err(psmouse, "Unable to initialize the device\n");
0315 return error;
0316 }
0317
0318 return 0;
0319 }
0320
0321 static void focaltech_set_input_params(struct psmouse *psmouse)
0322 {
0323 struct input_dev *dev = psmouse->dev;
0324 struct focaltech_data *priv = psmouse->private;
0325
0326
0327
0328
0329
0330 __clear_bit(EV_REL, dev->evbit);
0331 __clear_bit(REL_X, dev->relbit);
0332 __clear_bit(REL_Y, dev->relbit);
0333 __clear_bit(BTN_RIGHT, dev->keybit);
0334 __clear_bit(BTN_MIDDLE, dev->keybit);
0335
0336
0337
0338
0339 __set_bit(EV_ABS, dev->evbit);
0340 input_set_abs_params(dev, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0);
0341 input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0);
0342 input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
0343 input_mt_init_slots(dev, 5, INPUT_MT_POINTER);
0344 __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
0345 }
0346
0347 static int focaltech_read_register(struct ps2dev *ps2dev, int reg,
0348 unsigned char *param)
0349 {
0350 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11))
0351 return -EIO;
0352
0353 param[0] = 0;
0354 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
0355 return -EIO;
0356
0357 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
0358 return -EIO;
0359
0360 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
0361 return -EIO;
0362
0363 param[0] = reg;
0364 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
0365 return -EIO;
0366
0367 if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
0368 return -EIO;
0369
0370 return 0;
0371 }
0372
0373 static int focaltech_read_size(struct psmouse *psmouse)
0374 {
0375 struct ps2dev *ps2dev = &psmouse->ps2dev;
0376 struct focaltech_data *priv = psmouse->private;
0377 char param[3];
0378
0379 if (focaltech_read_register(ps2dev, 2, param))
0380 return -EIO;
0381
0382
0383 priv->x_max = (unsigned char)param[1] * 128;
0384 priv->y_max = (unsigned char)param[2] * 128;
0385
0386 return 0;
0387 }
0388
0389 static void focaltech_set_resolution(struct psmouse *psmouse,
0390 unsigned int resolution)
0391 {
0392
0393 }
0394
0395 static void focaltech_set_rate(struct psmouse *psmouse, unsigned int rate)
0396 {
0397
0398 }
0399
0400 static void focaltech_set_scale(struct psmouse *psmouse,
0401 enum psmouse_scale scale)
0402 {
0403
0404 }
0405
0406 int focaltech_init(struct psmouse *psmouse)
0407 {
0408 struct focaltech_data *priv;
0409 int error;
0410
0411 psmouse->private = priv = kzalloc(sizeof(struct focaltech_data),
0412 GFP_KERNEL);
0413 if (!priv)
0414 return -ENOMEM;
0415
0416 focaltech_reset(psmouse);
0417
0418 error = focaltech_read_size(psmouse);
0419 if (error) {
0420 psmouse_err(psmouse,
0421 "Unable to read the size of the touchpad\n");
0422 goto fail;
0423 }
0424
0425 error = focaltech_switch_protocol(psmouse);
0426 if (error) {
0427 psmouse_err(psmouse, "Unable to initialize the device\n");
0428 goto fail;
0429 }
0430
0431 focaltech_set_input_params(psmouse);
0432
0433 psmouse->protocol_handler = focaltech_process_byte;
0434 psmouse->pktsize = 6;
0435 psmouse->disconnect = focaltech_disconnect;
0436 psmouse->reconnect = focaltech_reconnect;
0437 psmouse->cleanup = focaltech_reset;
0438
0439 psmouse->resync_time = 0;
0440
0441
0442
0443
0444
0445 psmouse->set_resolution = focaltech_set_resolution;
0446 psmouse->set_rate = focaltech_set_rate;
0447 psmouse->set_scale = focaltech_set_scale;
0448
0449 return 0;
0450
0451 fail:
0452 focaltech_reset(psmouse);
0453 kfree(priv);
0454 return error;
0455 }
0456 #endif