diff options
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r-- | drivers/input/mouse/alps.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/bcm5974.c | 348 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 4 | ||||
-rw-r--r-- | drivers/input/mouse/hgpk.c | 9 | ||||
-rw-r--r-- | drivers/input/mouse/pxa930_trkball.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/rpcmouse.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/sentelic.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 35 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics_i2c.c | 7 |
9 files changed, 189 insertions, 222 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 4a1347e91bd..cf5af1f495e 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -1620,7 +1620,7 @@ int alps_init(struct psmouse *psmouse) case ALPS_PROTO_V3: case ALPS_PROTO_V4: set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); - input_mt_init_slots(dev1, 2); + input_mt_init_slots(dev1, 2, 0); input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0); input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0); diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index d528c23e194..3a78f235fa3 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -40,6 +40,7 @@ #include <linux/usb/input.h> #include <linux/hid.h> #include <linux/mutex.h> +#include <linux/input/mt.h> #define USB_VENDOR_ID_APPLE 0x05ac @@ -183,26 +184,26 @@ struct tp_finger { __le16 abs_y; /* absolute y coodinate */ __le16 rel_x; /* relative x coodinate */ __le16 rel_y; /* relative y coodinate */ - __le16 size_major; /* finger size, major axis? */ - __le16 size_minor; /* finger size, minor axis? */ + __le16 tool_major; /* tool area, major axis */ + __le16 tool_minor; /* tool area, minor axis */ __le16 orientation; /* 16384 when point, else 15 bit angle */ - __le16 force_major; /* trackpad force, major axis? */ - __le16 force_minor; /* trackpad force, minor axis? */ + __le16 touch_major; /* touch area, major axis */ + __le16 touch_minor; /* touch area, minor axis */ __le16 unused[3]; /* zeros */ __le16 multi; /* one finger: varies, more fingers: constant */ } __attribute__((packed,aligned(2))); /* trackpad finger data size, empirically at least ten fingers */ +#define MAX_FINGERS 16 #define SIZEOF_FINGER sizeof(struct tp_finger) -#define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) +#define SIZEOF_ALL_FINGERS (MAX_FINGERS * SIZEOF_FINGER) #define MAX_FINGER_ORIENTATION 16384 /* device-specific parameters */ struct bcm5974_param { - int dim; /* logical dimension */ - int fuzz; /* logical noise value */ - int devmin; /* device minimum reading */ - int devmax; /* device maximum reading */ + int snratio; /* signal-to-noise ratio */ + int min; /* device minimum reading */ + int max; /* device maximum reading */ }; /* device-specific configuration */ @@ -219,6 +220,7 @@ struct bcm5974_config { struct bcm5974_param w; /* finger width limits */ struct bcm5974_param x; /* horizontal limits */ struct bcm5974_param y; /* vertical limits */ + struct bcm5974_param o; /* orientation limits */ }; /* logical device structure */ @@ -234,23 +236,16 @@ struct bcm5974 { struct bt_data *bt_data; /* button transferred data */ struct urb *tp_urb; /* trackpad usb request block */ u8 *tp_data; /* trackpad transferred data */ - int fingers; /* number of fingers on trackpad */ + const struct tp_finger *index[MAX_FINGERS]; /* finger index data */ + struct input_mt_pos pos[MAX_FINGERS]; /* position array */ + int slots[MAX_FINGERS]; /* slot assignments */ }; -/* logical dimensions */ -#define DIM_PRESSURE 256 /* maximum finger pressure */ -#define DIM_WIDTH 16 /* maximum finger width */ -#define DIM_X 1280 /* maximum trackpad x value */ -#define DIM_Y 800 /* maximum trackpad y value */ - /* logical signal quality */ #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ -#define SN_WIDTH 100 /* width signal-to-noise ratio */ +#define SN_WIDTH 25 /* width signal-to-noise ratio */ #define SN_COORD 250 /* coordinate signal-to-noise ratio */ - -/* pressure thresholds */ -#define PRESSURE_LOW (2 * DIM_PRESSURE / SN_PRESSURE) -#define PRESSURE_HIGH (3 * PRESSURE_LOW) +#define SN_ORIENT 10 /* orientation signal-to-noise ratio */ /* device constants */ static const struct bcm5974_config bcm5974_config_table[] = { @@ -261,10 +256,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { 0, 0x84, sizeof(struct bt_data), 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4824, 5342 }, - { DIM_Y, DIM_Y / SN_COORD, -172, 5820 } + { SN_PRESSURE, 0, 256 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4824, 5342 }, + { SN_COORD, -172, 5820 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, { USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, @@ -273,10 +269,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { 0, 0x84, sizeof(struct bt_data), 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, - { DIM_Y, DIM_Y / SN_COORD, -172, 4290 } + { SN_PRESSURE, 0, 256 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4824, 4824 }, + { SN_COORD, -172, 4290 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, { USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, @@ -285,10 +282,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { HAS_INTEGRATED_BUTTON, 0x84, sizeof(struct bt_data), 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4460, 5166 }, - { DIM_Y, DIM_Y / SN_COORD, -75, 6700 } + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4460, 5166 }, + { SN_COORD, -75, 6700 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, { USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, @@ -297,10 +295,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { HAS_INTEGRATED_BUTTON, 0x84, sizeof(struct bt_data), 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, - { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4620, 5140 }, + { SN_COORD, -150, 6600 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, { USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, @@ -309,10 +308,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { HAS_INTEGRATED_BUTTON, 0x84, sizeof(struct bt_data), 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4616, 5112 }, - { DIM_Y, DIM_Y / SN_COORD, -142, 5234 } + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4616, 5112 }, + { SN_COORD, -142, 5234 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, { USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI, @@ -321,10 +321,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { HAS_INTEGRATED_BUTTON, 0x84, sizeof(struct bt_data), 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4415, 5050 }, - { DIM_Y, DIM_Y / SN_COORD, -55, 6680 } + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4415, 5050 }, + { SN_COORD, -55, 6680 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, { USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI, @@ -333,10 +334,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { HAS_INTEGRATED_BUTTON, 0x84, sizeof(struct bt_data), 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, - { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4620, 5140 }, + { SN_COORD, -150, 6600 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, { USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI, @@ -345,10 +347,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { HAS_INTEGRATED_BUTTON, 0x84, sizeof(struct bt_data), 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, - { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4750, 5280 }, + { SN_COORD, -150, 6730 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, { USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI, @@ -357,10 +360,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { HAS_INTEGRATED_BUTTON, 0x84, sizeof(struct bt_data), 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, - { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4620, 5140 }, + { SN_COORD, -150, 6600 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, { USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI, @@ -369,10 +373,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { HAS_INTEGRATED_BUTTON, 0x84, sizeof(struct bt_data), 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, - { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, - { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, - { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, - { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4750, 5280 }, + { SN_COORD, -150, 6730 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } }, {} }; @@ -396,18 +401,11 @@ static inline int raw2int(__le16 x) return (signed short)le16_to_cpu(x); } -/* scale device data to logical dimensions (asserts devmin < devmax) */ -static inline int int2scale(const struct bcm5974_param *p, int x) -{ - return x * p->dim / (p->devmax - p->devmin); -} - -/* all logical value ranges are [0,dim). */ -static inline int int2bound(const struct bcm5974_param *p, int x) +static void set_abs(struct input_dev *input, unsigned int code, + const struct bcm5974_param *p) { - int s = int2scale(p, x); - - return clamp_val(s, 0, p->dim - 1); + int fuzz = p->snratio ? (p->max - p->min) / p->snratio : 0; + input_set_abs_params(input, code, p->min, p->max, fuzz, 0); } /* setup which logical events to report */ @@ -416,48 +414,30 @@ static void setup_events_to_report(struct input_dev *input_dev, { __set_bit(EV_ABS, input_dev->evbit); - input_set_abs_params(input_dev, ABS_PRESSURE, - 0, cfg->p.dim, cfg->p.fuzz, 0); - input_set_abs_params(input_dev, ABS_TOOL_WIDTH, - 0, cfg->w.dim, cfg->w.fuzz, 0); - input_set_abs_params(input_dev, ABS_X, - 0, cfg->x.dim, cfg->x.fuzz, 0); - input_set_abs_params(input_dev, ABS_Y, - 0, cfg->y.dim, cfg->y.fuzz, 0); + /* for synaptics only */ + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 256, 5, 0); + input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 16, 0, 0); /* finger touch area */ - input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, - cfg->w.devmin, cfg->w.devmax, 0, 0); - input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, - cfg->w.devmin, cfg->w.devmax, 0, 0); + set_abs(input_dev, ABS_MT_TOUCH_MAJOR, &cfg->w); + set_abs(input_dev, ABS_MT_TOUCH_MINOR, &cfg->w); /* finger approach area */ - input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, - cfg->w.devmin, cfg->w.devmax, 0, 0); - input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, - cfg->w.devmin, cfg->w.devmax, 0, 0); + set_abs(input_dev, ABS_MT_WIDTH_MAJOR, &cfg->w); + set_abs(input_dev, ABS_MT_WIDTH_MINOR, &cfg->w); /* finger orientation */ - input_set_abs_params(input_dev, ABS_MT_ORIENTATION, - -MAX_FINGER_ORIENTATION, - MAX_FINGER_ORIENTATION, 0, 0); + set_abs(input_dev, ABS_MT_ORIENTATION, &cfg->o); /* finger position */ - input_set_abs_params(input_dev, ABS_MT_POSITION_X, - cfg->x.devmin, cfg->x.devmax, 0, 0); - input_set_abs_params(input_dev, ABS_MT_POSITION_Y, - cfg->y.devmin, cfg->y.devmax, 0, 0); + set_abs(input_dev, ABS_MT_POSITION_X, &cfg->x); + set_abs(input_dev, ABS_MT_POSITION_Y, &cfg->y); __set_bit(EV_KEY, input_dev->evbit); - __set_bit(BTN_TOUCH, input_dev->keybit); - __set_bit(BTN_TOOL_FINGER, input_dev->keybit); - __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); - __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); - __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); __set_bit(BTN_LEFT, input_dev->keybit); - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); if (cfg->caps & HAS_INTEGRATED_BUTTON) __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); - input_set_events_per_packet(input_dev, 60); + input_mt_init_slots(input_dev, MAX_FINGERS, + INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); } /* report button data as logical button state */ @@ -477,24 +457,44 @@ static int report_bt_state(struct bcm5974 *dev, int size) return 0; } -static void report_finger_data(struct input_dev *input, - const struct bcm5974_config *cfg, +static void report_finger_data(struct input_dev *input, int slot, + const struct input_mt_pos *pos, const struct tp_finger *f) { + input_mt_slot(input, slot); + input_mt_report_slot_state(input, MT_TOOL_FINGER, true); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, - raw2int(f->force_major) << 1); + raw2int(f->touch_major) << 1); input_report_abs(input, ABS_MT_TOUCH_MINOR, - raw2int(f->force_minor) << 1); + raw2int(f->touch_minor) << 1); input_report_abs(input, ABS_MT_WIDTH_MAJOR, - raw2int(f->size_major) << 1); + raw2int(f->tool_major) << 1); input_report_abs(input, ABS_MT_WIDTH_MINOR, - raw2int(f->size_minor) << 1); + raw2int(f->tool_minor) << 1); input_report_abs(input, ABS_MT_ORIENTATION, MAX_FINGER_ORIENTATION - raw2int(f->orientation)); - input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); - input_report_abs(input, ABS_MT_POSITION_Y, - cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y)); - input_mt_sync(input); + input_report_abs(input, ABS_MT_POSITION_X, pos->x); + input_report_abs(input, ABS_MT_POSITION_Y, pos->y); +} + +static void report_synaptics_data(struct input_dev *input, + const struct bcm5974_config *cfg, + const struct tp_finger *f, int raw_n) +{ + int abs_p = 0, abs_w = 0; + + if (raw_n) { + int p = raw2int(f->touch_major); + int w = raw2int(f->tool_major); + if (p > 0 && raw2int(f->origin)) { + abs_p = clamp_val(256 * p / cfg->p.max, 0, 255); + abs_w = clamp_val(16 * w / cfg->w.max, 0, 15); + } + } + + input_report_abs(input, ABS_PRESSURE, abs_p); + input_report_abs(input, ABS_TOOL_WIDTH, abs_w); } /* report trackpad data as logical trackpad state */ @@ -503,9 +503,7 @@ static int report_tp_state(struct bcm5974 *dev, int size) const struct bcm5974_config *c = &dev->cfg; const struct tp_finger *f; struct input_dev *input = dev->input; - int raw_p, raw_w, raw_x, raw_y, raw_n, i; - int ptest, origin, ibt = 0, nmin = 0, nmax = 0; - int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; + int raw_n, i, n = 0; if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) return -EIO; @@ -514,76 +512,29 @@ static int report_tp_state(struct bcm5974 *dev, int size) f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); raw_n = (size - c->tp_offset) / SIZEOF_FINGER; - /* always track the first finger; when detached, start over */ - if (raw_n) { - - /* report raw trackpad data */ - for (i = 0; i < raw_n; i++) - report_finger_data(input, c, &f[i]); - - raw_p = raw2int(f->force_major); - raw_w = raw2int(f->size_major); - raw_x = raw2int(f->abs_x); - raw_y = raw2int(f->abs_y); - - dprintk(9, - "bcm5974: " - "raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n", - raw_p, raw_w, raw_x, raw_y, raw_n); - - ptest = int2bound(&c->p, raw_p); - origin = raw2int(f->origin); - - /* while tracking finger still valid, count all fingers */ - if (ptest > PRESSURE_LOW && origin) { - abs_p = ptest; - abs_w = int2bound(&c->w, raw_w); - abs_x = int2bound(&c->x, raw_x - c->x.devmin); - abs_y = int2bound(&c->y, c->y.devmax - raw_y); - while (raw_n--) { - ptest = int2bound(&c->p, - raw2int(f->force_major)); - if (ptest > PRESSURE_LOW) - nmax++; - if (ptest > PRESSURE_HIGH) - nmin++; - f++; - } - } + for (i = 0; i < raw_n; i++) { + if (raw2int(f[i].touch_major) == 0) + continue; + dev->pos[n].x = raw2int(f[i].abs_x); + dev->pos[n].y = c->y.min + c->y.max - raw2int(f[i].abs_y); + dev->index[n++] = &f[i]; } - /* set the integrated button if applicable */ - if (c->tp_type == TYPE2) - ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); - - if (dev->fingers < nmin) - dev->fingers = nmin; - if (dev->fingers > nmax) - dev->fingers = nmax; - - input_report_key(input, BTN_TOUCH, dev->fingers > 0); - input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1); - input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2); - input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers == 3); - input_report_key(input, BTN_TOOL_QUADTAP, dev->fingers > 3); - - input_report_abs(input, ABS_PRESSURE, abs_p); - input_report_abs(input, ABS_TOOL_WIDTH, abs_w); + input_mt_assign_slots(input, dev->slots, dev->pos, n); - if (abs_p) { - input_report_abs(input, ABS_X, abs_x); - input_report_abs(input, ABS_Y, abs_y); + for (i = 0; i < n; i++) + report_finger_data(input, dev->slots[i], + &dev->pos[i], dev->index[i]); - dprintk(8, - "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d " - "nmin: %d nmax: %d n: %d ibt: %d\n", abs_p, abs_w, - abs_x, abs_y, nmin, nmax, dev->fingers, ibt); + input_mt_sync_frame(input); - } + report_synaptics_data(input, c, f, raw_n); /* type 2 reports button events via ibt only */ - if (c->tp_type == TYPE2) + if (c->tp_type == TYPE2) { + int ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); input_report_key(input, BTN_LEFT, ibt); + } input_sync(input); @@ -742,9 +693,11 @@ static int bcm5974_start_traffic(struct bcm5974 *dev) goto err_out; } - error = usb_submit_urb(dev->bt_urb, GFP_KERNEL); - if (error) - goto err_reset_mode; + if (dev->bt_urb) { + error = usb_submit_urb(dev->bt_urb, GFP_KERNEL); + if (error) + goto err_reset_mode; + } error = usb_submit_urb(dev->tp_urb, GFP_KERNEL); if (error) @@ -868,19 +821,23 @@ static int bcm5974_probe(struct usb_interface *iface, mutex_init(&dev->pm_mutex); /* setup urbs */ - dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!dev->bt_urb) - goto err_free_devs; + if (cfg->tp_type == TYPE1) { + dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->bt_urb) + goto err_free_devs; + } dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->tp_urb) goto err_free_bt_urb; - dev->bt_data = usb_alloc_coherent(dev->udev, + if (dev->bt_urb) { + dev->bt_data = usb_alloc_coherent(dev->udev, dev->cfg.bt_datalen, GFP_KERNEL, &dev->bt_urb->transfer_dma); - if (!dev->bt_data) - goto err_free_urb; + if (!dev->bt_data) + goto err_free_urb; + } dev->tp_data = usb_alloc_coherent(dev->udev, dev->cfg.tp_datalen, GFP_KERNEL, @@ -888,10 +845,11 @@ static int bcm5974_probe(struct usb_interface *iface, if (!dev->tp_data) goto err_free_bt_buffer; - usb_fill_int_urb(dev->bt_urb, udev, - usb_rcvintpipe(udev, cfg->bt_ep), - dev->bt_data, dev->cfg.bt_datalen, - bcm5974_irq_button, dev, 1); + if (dev->bt_urb) + usb_fill_int_urb(dev->bt_urb, udev, + usb_rcvintpipe(udev, cfg->bt_ep), + dev->bt_data, dev->cfg.bt_datalen, + bcm5974_irq_button, dev, 1); usb_fill_int_urb(dev->tp_urb, udev, usb_rcvintpipe(udev, cfg->tp_ep), @@ -929,8 +887,9 @@ err_free_buffer: usb_free_coherent(dev->udev, dev->cfg.tp_datalen, dev->tp_data, dev->tp_urb->transfer_dma); err_free_bt_buffer: - usb_free_coherent(dev->udev, dev->cfg.bt_datalen, - dev->bt_data, dev->bt_urb->transfer_dma); + if (dev->bt_urb) + usb_free_coherent(dev->udev, dev->cfg.bt_datalen, + dev->bt_data, dev->bt_urb->transfer_dma); err_free_urb: usb_free_urb(dev->tp_urb); err_free_bt_urb: @@ -951,8 +910,9 @@ static void bcm5974_disconnect(struct usb_interface *iface) input_unregister_device(dev->input); usb_free_coherent(dev->udev, dev->cfg.tp_datalen, dev->tp_data, dev->tp_urb->transfer_dma); - usb_free_coherent(dev->udev, dev->cfg.bt_datalen, - dev->bt_data, dev->bt_urb->transfer_dma); + if (dev->bt_urb) + usb_free_coherent(dev->udev, dev->cfg.bt_datalen, + dev->bt_data, dev->bt_urb->transfer_dma); usb_free_urb(dev->tp_urb); usb_free_urb(dev->bt_urb); kfree(dev); diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 479011004a1..1e8e42fb03a 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1004,7 +1004,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, ETP_WMAX_V2, 0, 0); } - input_mt_init_slots(dev, 2); + input_mt_init_slots(dev, 2, 0); input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); break; @@ -1035,7 +1035,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, ETP_WMAX_V2, 0, 0); /* Multitouch capable pad, up to 5 fingers. */ - input_mt_init_slots(dev, ETP_MAX_FINGERS); + input_mt_init_slots(dev, ETP_MAX_FINGERS, 0); input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); input_abs_set_res(dev, ABS_MT_POSITION_X, x_res); diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 575f880727f..62be888e83d 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -334,11 +334,8 @@ static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet) if (!valid) psmouse_dbg(psmouse, - "bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n", - priv->mode, pktcnt, - psmouse->packet[0], psmouse->packet[1], - psmouse->packet[2], psmouse->packet[3], - psmouse->packet[4], psmouse->packet[5]); + "bad data, mode %d (%d) %*ph\n", + priv->mode, pktcnt, 6, psmouse->packet); return valid; } @@ -1030,7 +1027,7 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse) return -EIO; } - psmouse_dbg(psmouse, "ID: %02x %02x %02x\n", param[0], param[1], param[2]); + psmouse_dbg(psmouse, "ID: %*ph\n", 3, param); /* HGPK signature: 0x67, 0x00, 0x<model> */ if (param[0] != 0x67 || param[1] != 0x00) diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index a9e4bfdf31f..4fe055f2c53 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c @@ -20,7 +20,7 @@ #include <linux/slab.h> #include <mach/hardware.h> -#include <mach/pxa930_trkball.h> +#include <linux/platform_data/mouse-pxa930_trkball.h> /* Trackball Controller Register Definitions */ #define TBCR (0x000C) diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c index 272deddc8db..21c60fea5d3 100644 --- a/drivers/input/mouse/rpcmouse.c +++ b/drivers/input/mouse/rpcmouse.c @@ -42,7 +42,7 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id) x = (short) iomd_readl(IOMD_MOUSEX); y = (short) iomd_readl(IOMD_MOUSEY); - b = (short) (__raw_readl(0xe0310000) ^ 0x70); + b = (short) (__raw_readl(IOMEM(0xe0310000)) ^ 0x70); dx = x - rpcmouse_lastx; dy = y - rpcmouse_lasty; diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index a261d857691..e582922bacf 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c @@ -971,7 +971,7 @@ static int fsp_set_input_params(struct psmouse *psmouse) input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0); input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0); - input_mt_init_slots(dev, 2); + input_mt_init_slots(dev, 2, 0); input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0); input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0); } diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 14eaecea2b7..12d12ca3fee 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -53,14 +53,19 @@ #define ABS_POS_BITS 13 /* - * Any position values from the hardware above the following limits are - * treated as "wrapped around negative" values that have been truncated to - * the 13-bit reporting range of the hardware. These are just reasonable - * guesses and can be adjusted if hardware is found that operates outside - * of these parameters. + * These values should represent the absolute maximum value that will + * be reported for a positive position value. Some Synaptics firmware + * uses this value to indicate a finger near the edge of the touchpad + * whose precise position cannot be determined. + * + * At least one touchpad is known to report positions in excess of this + * value which are actually negative values truncated to the 13-bit + * reporting range. These values have never been observed to be lower + * than 8184 (i.e. -8), so we treat all values greater than 8176 as + * negative and any other value as positive. */ -#define X_MAX_POSITIVE (((1 << ABS_POS_BITS) + XMAX) / 2) -#define Y_MAX_POSITIVE (((1 << ABS_POS_BITS) + YMAX) / 2) +#define X_MAX_POSITIVE 8176 +#define Y_MAX_POSITIVE 8176 /***************************************************************************** * Stuff we need even when we do not want native Synaptics support @@ -604,11 +609,21 @@ static int synaptics_parse_hw_state(const unsigned char buf[], hw->right = (buf[0] & 0x02) ? 1 : 0; } - /* Convert wrap-around values to negative */ + /* + * Convert wrap-around values to negative. (X|Y)_MAX_POSITIVE + * is used by some firmware to indicate a finger at the edge of + * the touchpad whose precise position cannot be determined, so + * convert these values to the maximum axis value. + */ if (hw->x > X_MAX_POSITIVE) hw->x -= 1 << ABS_POS_BITS; + else if (hw->x == X_MAX_POSITIVE) + hw->x = XMAX; + if (hw->y > Y_MAX_POSITIVE) hw->y -= 1 << ABS_POS_BITS; + else if (hw->y == Y_MAX_POSITIVE) + hw->y = YMAX; return 0; } @@ -1232,7 +1247,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { - input_mt_init_slots(dev, 2); + input_mt_init_slots(dev, 2, 0); set_abs_position_params(dev, priv, ABS_MT_POSITION_X, ABS_MT_POSITION_Y); /* Image sensors can report per-contact pressure */ @@ -1244,7 +1259,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { /* Non-image sensors with AGM use semi-mt */ __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); - input_mt_init_slots(dev, 2); + input_mt_init_slots(dev, 2, 0); set_abs_position_params(dev, priv, ABS_MT_POSITION_X, ABS_MT_POSITION_Y); } diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index f14675702c0..063a174d3a8 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c @@ -376,12 +376,7 @@ static void synaptics_i2c_reschedule_work(struct synaptics_i2c *touch, spin_lock_irqsave(&touch->lock, flags); - /* - * If work is already scheduled then subsequent schedules will not - * change the scheduled time that's why we have to cancel it first. - */ - __cancel_delayed_work(&touch->dwork); - schedule_delayed_work(&touch->dwork, delay); + mod_delayed_work(system_wq, &touch->dwork, delay); spin_unlock_irqrestore(&touch->lock, flags); } |