aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/hgpk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse/hgpk.c')
-rw-r--r--drivers/input/mouse/hgpk.c61
1 files changed, 55 insertions, 6 deletions
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index a1ad2f1a7bb..de1e553028b 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -367,7 +367,36 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
367} 367}
368 368
369__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL, 369__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
370 hgpk_show_powered, hgpk_set_powered, 0); 370 hgpk_show_powered, hgpk_set_powered, false);
371
372static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,
373 void *data, char *buf)
374{
375 return -EINVAL;
376}
377
378static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data,
379 const char *buf, size_t count)
380{
381 struct hgpk_data *priv = psmouse->private;
382 unsigned long value;
383 int err;
384
385 err = strict_strtoul(buf, 10, &value);
386 if (err || value != 1)
387 return -EINVAL;
388
389 /*
390 * We queue work instead of doing recalibration right here
391 * to avoid adding locking to to hgpk_force_recalibrate()
392 * since workqueue provides serialization.
393 */
394 psmouse_queue_work(psmouse, &priv->recalib_wq, 0);
395 return count;
396}
397
398__PSMOUSE_DEFINE_ATTR(recalibrate, S_IWUSR | S_IRUGO, NULL,
399 hgpk_trigger_recal_show, hgpk_trigger_recal, false);
371 400
372static void hgpk_disconnect(struct psmouse *psmouse) 401static void hgpk_disconnect(struct psmouse *psmouse)
373{ 402{
@@ -375,6 +404,11 @@ static void hgpk_disconnect(struct psmouse *psmouse)
375 404
376 device_remove_file(&psmouse->ps2dev.serio->dev, 405 device_remove_file(&psmouse->ps2dev.serio->dev,
377 &psmouse_attr_powered.dattr); 406 &psmouse_attr_powered.dattr);
407
408 if (psmouse->model >= HGPK_MODEL_C)
409 device_remove_file(&psmouse->ps2dev.serio->dev,
410 &psmouse_attr_recalibrate.dattr);
411
378 psmouse_reset(psmouse); 412 psmouse_reset(psmouse);
379 kfree(priv); 413 kfree(priv);
380} 414}
@@ -423,10 +457,25 @@ static int hgpk_register(struct psmouse *psmouse)
423 457
424 err = device_create_file(&psmouse->ps2dev.serio->dev, 458 err = device_create_file(&psmouse->ps2dev.serio->dev,
425 &psmouse_attr_powered.dattr); 459 &psmouse_attr_powered.dattr);
426 if (err) 460 if (err) {
427 hgpk_err(psmouse, "Failed to create sysfs attribute\n"); 461 hgpk_err(psmouse, "Failed creating 'powered' sysfs node\n");
462 return err;
463 }
428 464
429 return err; 465 /* C-series touchpads added the recalibrate command */
466 if (psmouse->model >= HGPK_MODEL_C) {
467 err = device_create_file(&psmouse->ps2dev.serio->dev,
468 &psmouse_attr_recalibrate.dattr);
469 if (err) {
470 hgpk_err(psmouse,
471 "Failed creating 'recalibrate' sysfs node\n");
472 device_remove_file(&psmouse->ps2dev.serio->dev,
473 &psmouse_attr_powered.dattr);
474 return err;
475 }
476 }
477
478 return 0;
430} 479}
431 480
432int hgpk_init(struct psmouse *psmouse) 481int hgpk_init(struct psmouse *psmouse)
@@ -440,7 +489,7 @@ int hgpk_init(struct psmouse *psmouse)
440 489
441 psmouse->private = priv; 490 psmouse->private = priv;
442 priv->psmouse = psmouse; 491 priv->psmouse = psmouse;
443 priv->powered = 1; 492 priv->powered = true;
444 INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work); 493 INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
445 494
446 err = psmouse_reset(psmouse); 495 err = psmouse_reset(psmouse);
@@ -483,7 +532,7 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
483 return param[2]; 532 return param[2];
484} 533}
485 534
486int hgpk_detect(struct psmouse *psmouse, int set_properties) 535int hgpk_detect(struct psmouse *psmouse, bool set_properties)
487{ 536{
488 int version; 537 int version;
489 538