lkml.org 
[lkml]   [2009]   [Jun]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH] forced recalibration for the OLPC hgpk touchpad
    From
    Date
    The OLPC XO laptop incorporates a combination touchpad/tablet
    device which unfortunately requires frequent recalibration. The
    driver will force this automatically when various suspicious
    behaviors are observed, and the user can recalibrate manually
    (with a special keyboard sequence). There's currently no way,
    however, for an external program to cause recalibration.

    This patch creates a new node in /sys which, when written with '1',
    will force a touchpad recalibration. No other writes (or reads)
    of this node are supported.

    paul

    --------------------


    Signed-off-by: Paul Fox <pgf@foxharp.boston.ma.us>

    diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
    index a1ad2f1..e736ebd 100644
    --- a/drivers/input/mouse/hgpk.c
    +++ b/drivers/input/mouse/hgpk.c
    @@ -369,12 +369,40 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
    __PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
    hgpk_show_powered, hgpk_set_powered, 0);

    +static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,
    + void *data, char *buf)
    +{
    + return -EINVAL;
    +}
    +
    +static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data,
    + const char *buf, size_t count)
    +{
    + struct hgpk_data *priv = psmouse->private;
    + unsigned long value;
    + int err;
    +
    + err = strict_strtoul(buf, 10, &value);
    + if (err || value != 1)
    + return -EINVAL;
    +
    + psmouse_queue_work(psmouse, &priv->recalib_wq,
    + msecs_to_jiffies(1));
    +
    + return count;
    +}
    +
    +__PSMOUSE_DEFINE_ATTR(recalibrate, S_IWUSR | S_IRUGO, NULL,
    + hgpk_trigger_recal_show, hgpk_trigger_recal, 0);
    +
    static void hgpk_disconnect(struct psmouse *psmouse)
    {
    struct hgpk_data *priv = psmouse->private;

    device_remove_file(&psmouse->ps2dev.serio->dev,
    &psmouse_attr_powered.dattr);
    + device_remove_file(&psmouse->ps2dev.serio->dev,
    + &psmouse_attr_recalibrate.dattr);
    psmouse_reset(psmouse);
    kfree(priv);
    }
    @@ -423,8 +451,18 @@ static int hgpk_register(struct psmouse *psmouse)

    err = device_create_file(&psmouse->ps2dev.serio->dev,
    &psmouse_attr_powered.dattr);
    - if (err)
    - hgpk_err(psmouse, "Failed to create sysfs attribute\n");
    + if (err) {
    + hgpk_err(psmouse, "Failed creating 'powered' sysfs node\n");
    + } else {
    + err = device_create_file(&psmouse->ps2dev.serio->dev,
    + &psmouse_attr_recalibrate.dattr);
    + if (err) {
    + hgpk_err(psmouse,
    + "Failed creating 'recalibrate' sysfs node\n");
    + device_remove_file(&psmouse->ps2dev.serio->dev,
    + &psmouse_attr_powered.dattr);
    + }
    + }

    return err;
    }


    =---------------------
    paul fox, pgf@laptop.org

    \
     
     \ /
      Last update: 2009-06-02 22:09    [W:0.023 / U:1.540 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site