···11+Kernel driver for CMA3000-D0x22+============================33+44+Supported chips:55+* VTI CMA3000-D0x66+Datasheet:77+ CMA3000-D0X Product Family Specification 8281000A.02.pdf88+ <http://www.vti.fi/en/>99+1010+Author: Hemanth V <hemanthv@ti.com>1111+1212+1313+Description1414+-----------1515+CMA3000 Tri-axis accelerometer supports Motion detect, Measurement and1616+Free fall modes.1717+1818+Motion Detect Mode: Its the low power mode where interrupts are generated only1919+when motion exceeds the defined thresholds.2020+2121+Measurement Mode: This mode is used to read the acceleration data on X,Y,Z2222+axis and supports 400, 100, 40 Hz sample frequency.2323+2424+Free fall Mode: This mode is intended to save system resources.2525+2626+Threshold values: Chip supports defining threshold values for above modes2727+which includes time and g value. Refer product specifications for more details.2828+2929+CMA3000 chip supports mutually exclusive I2C and SPI interfaces for3030+communication, currently the driver supports I2C based communication only.3131+Initial configuration for bus mode is set in non volatile memory and can later3232+be modified through bus interface command.3333+3434+Driver reports acceleration data through input subsystem. It generates ABS_MISC3535+event with value 1 when free fall is detected.3636+3737+Platform data need to be configured for initial default values.3838+3939+Platform Data4040+-------------4141+fuzz_x: Noise on X Axis4242+4343+fuzz_y: Noise on Y Axis4444+4545+fuzz_z: Noise on Z Axis4646+4747+g_range: G range in milli g i.e 2000 or 80004848+4949+mode: Default Operating mode5050+5151+mdthr: Motion detect g range threshold value5252+5353+mdfftmr: Motion detect and free fall time threshold value5454+5555+ffthr: Free fall g range threshold value5656+5757+Input Interface5858+--------------5959+Input driver version is 1.0.06060+Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x06161+Input device name: "cma3000-accelerometer"6262+Supported events:6363+ Event type 0 (Sync)6464+ Event type 3 (Absolute)6565+ Event code 0 (X)6666+ Value 476767+ Min -80006868+ Max 80006969+ Fuzz 2007070+ Event code 1 (Y)7171+ Value -287272+ Min -80007373+ Max 80007474+ Fuzz 2007575+ Event code 2 (Z)7676+ Value 9057777+ Min -80007878+ Max 80007979+ Fuzz 2008080+ Event code 40 (Misc)8181+ Value 08282+ Min 08383+ Max 18484+ Event type 4 (Misc)8585+8686+8787+Register/Platform parameters Description8888+----------------------------------------8989+9090+mode:9191+ 0: power down mode9292+ 1: 100 Hz Measurement mode9393+ 2: 400 Hz Measurement mode9494+ 3: 40 Hz Measurement mode9595+ 4: Motion Detect mode (default)9696+ 5: 100 Hz Free fall mode9797+ 6: 40 Hz Free fall mode9898+ 7: Power off mode9999+100100+grange:101101+ 2000: 2000 mg or 2G Range102102+ 8000: 8000 mg or 8G Range103103+104104+mdthr:105105+ X: X * 71mg (8G Range)106106+ X: X * 18mg (2G Range)107107+108108+mdfftmr:109109+ X: (X & 0x70) * 100 ms (MDTMR)110110+ (X & 0x0F) * 2.5 ms (FFTMR 400 Hz)111111+ (X & 0x0F) * 10 ms (FFTMR 100 Hz)112112+113113+ffthr:114114+ X: (X >> 2) * 18mg (2G Range)115115+ X: (X & 0x0F) * 71 mg (8G Range)
+34-19
Documentation/input/multi-touch-protocol.txt
···11Multi-touch (MT) Protocol22-------------------------33- Copyright (C) 2009 Henrik Rydberg <rydberg@euromail.se>33+ Copyright (C) 2009-2010 Henrik Rydberg <rydberg@euromail.se>445566Introduction···161161ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR, which is always smaller than162162unity, is related to the contact pressure. For pressure-based devices,163163ABS_MT_PRESSURE may be used to provide the pressure on the contact area164164-instead.164164+instead. Devices capable of contact hovering can use ABS_MT_DISTANCE to165165+indicate the distance between the contact and the surface.165166166167In addition to the MAJOR parameters, the oval shape of the contact can be167168described by adding the MINOR parameters, such that MAJOR and MINOR are the168169major and minor axis of an ellipse. Finally, the orientation of the oval169170shape can be describe with the ORIENTATION parameter.170171172172+For type A devices, further specification of the touch shape is possible173173+via ABS_MT_BLOB_ID.174174+171175The ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a172172-contact or a pen or something else. Devices with more granular information173173-may specify general shapes as blobs, i.e., as a sequence of rectangular174174-shapes grouped together by an ABS_MT_BLOB_ID. Finally, for the few devices175175-that currently support it, the ABS_MT_TRACKING_ID event may be used to176176-report contact tracking from hardware [5].176176+finger or a pen or something else. Finally, the ABS_MT_TRACKING_ID event177177+may be used to track identified contacts over time [5].178178+179179+In the type B protocol, ABS_MT_TOOL_TYPE and ABS_MT_TRACKING_ID are180180+implicitly handled by input core; drivers should instead call181181+input_mt_report_slot_state().177182178183179184Event Semantics···218213of TOUCH and WIDTH for pressure-based devices or any device with a spatial219214signal intensity distribution.220215216216+ABS_MT_DISTANCE217217+218218+The distance, in surface units, between the contact and the surface. Zero219219+distance means the contact is touching the surface. A positive number means220220+the contact is hovering above the surface.221221+221222ABS_MT_ORIENTATION222223223224The orientation of the ellipse. The value should describe a signed quarter···251240The type of approaching tool. A lot of kernel drivers cannot distinguish252241between different tool types, such as a finger or a pen. In such cases, the253242event should be omitted. The protocol currently supports MT_TOOL_FINGER and254254-MT_TOOL_PEN [2].243243+MT_TOOL_PEN [2]. For type B devices, this event is handled by input core;244244+drivers should instead use input_mt_report_slot_state().255245256246ABS_MT_BLOB_ID257247258248The BLOB_ID groups several packets together into one arbitrarily shaped259259-contact. This is a low-level anonymous grouping for type A devices, and249249+contact. The sequence of points forms a polygon which defines the shape of250250+the contact. This is a low-level anonymous grouping for type A devices, and260251should not be confused with the high-level trackingID [5]. Most type A261252devices do not have blob capability, so drivers can safely omit this event.262253263254ABS_MT_TRACKING_ID264255265256The TRACKING_ID identifies an initiated contact throughout its life cycle266266-[5]. This event is mandatory for type B devices. The value range of the267267-TRACKING_ID should be large enough to ensure unique identification of a268268-contact maintained over an extended period of time.257257+[5]. The value range of the TRACKING_ID should be large enough to ensure258258+unique identification of a contact maintained over an extended period of259259+time. For type B devices, this event is handled by input core; drivers260260+should instead use input_mt_report_slot_state().269261270262271263Event Computation···315301Notes316302-----317303318318-In order to stay compatible with existing applications, the data319319-reported in a finger packet must not be recognized as single-touch320320-events. In addition, all finger data must bypass input filtering,321321-since subsequent events of the same type refer to different fingers.304304+In order to stay compatible with existing applications, the data reported305305+in a finger packet must not be recognized as single-touch events.322306323323-The first kernel driver to utilize the MT protocol is the bcm5974 driver,324324-where examples can be found.307307+For type A devices, all finger data bypasses input filtering, since308308+subsequent events of the same type refer to different fingers.309309+310310+For example usage of the type A protocol, see the bcm5974 driver. For311311+example usage of the type B protocol, see the hid-egalax driver.325312326313[1] With the extension ABS_MT_APPROACH_X and ABS_MT_APPROACH_Y, the327314difference between the contact position and the approaching tool position328315could be used to derive tilt.329316[2] The list can of course be extended.330330-[3] Multitouch X driver project: http://bitmath.org/code/multitouch/.317317+[3] The mtdev project: http://bitmath.org/code/mtdev/.331318[4] See the section on event computation.332319[5] See the section on finger tracking.
···154154 tristate "eGalax multi-touch panel"155155 depends on USB_HID156156 ---help---157157- Support for the eGalax dual-touch panel.157157+ Support for the eGalax dual-touch panels, including the158158+ Joojoo and Wetab tablets.158159159160config HID_ELECOM160161 tristate "ELECOM BM084 bluetooth mouse"
+4-32
drivers/hid/hid-3m-pct.c
···1919#include <linux/module.h>2020#include <linux/slab.h>2121#include <linux/usb.h>2222+#include <linux/input/mt.h>22232324MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");2425MODULE_DESCRIPTION("3M PCT multitouch panels");···2827#include "hid-ids.h"29283029#define MAX_SLOTS 603131-#define MAX_TRKID USHRT_MAX3232-#define MAX_EVENTS 36033303431/* estimated signal-to-noise ratios */3532#define SN_MOVE 2048···35363637struct mmm_finger {3738 __s32 x, y, w, h;3838- __u16 id;3939- bool prev_touch;4039 bool touch, valid;4140};42414342struct mmm_data {4443 struct mmm_finger f[MAX_SLOTS];4545- __u16 id;4644 __u8 curid;4745 __u8 nexp, nreal;4846 bool touch, valid;···113117 0, 1, 0, 0);114118 return 1;115119 case HID_DG_CONTACTID:116116- field->logical_maximum = MAX_TRKID;117117- hid_map_usage(hi, usage, bit, max,118118- EV_ABS, ABS_MT_TRACKING_ID);119119- input_set_abs_params(hi->input, ABS_MT_TRACKING_ID,120120- 0, MAX_TRKID, 0, 0);121121- if (!hi->input->mt)122122- input_mt_create_slots(hi->input, MAX_SLOTS);123123- input_set_events_per_packet(hi->input, MAX_EVENTS);120120+ input_mt_init_slots(hi->input, MAX_SLOTS);124121 return 1;125122 }126123 /* let hid-input decide for the others */···143154 */144155static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)145156{146146- struct mmm_finger *oldest = 0;147157 int i;148158 for (i = 0; i < MAX_SLOTS; ++i) {149159 struct mmm_finger *f = &md->f[i];···151163 continue;152164 }153165 input_mt_slot(input, i);166166+ input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch);154167 if (f->touch) {155168 /* this finger is on the screen */156169 int wide = (f->w > f->h);···159170 int major = max(f->w, f->h) >> 1;160171 int minor = min(f->w, f->h) >> 1;161172162162- if (!f->prev_touch)163163- f->id = md->id++;164164- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id);165173 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);166174 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);167175 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);168176 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);169177 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);170170- /* touchscreen emulation: pick the oldest contact */171171- if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1)))172172- oldest = f;173173- } else {174174- /* this finger took off the screen */175175- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1);176178 }177177- f->prev_touch = f->touch;178179 f->valid = 0;179180 }180181181181- /* touchscreen emulation */182182- if (oldest) {183183- input_event(input, EV_KEY, BTN_TOUCH, 1);184184- input_event(input, EV_ABS, ABS_X, oldest->x);185185- input_event(input, EV_ABS, ABS_Y, oldest->y);186186- } else {187187- input_event(input, EV_KEY, BTN_TOUCH, 0);188188- }182182+ input_mt_report_pointer_emulation(input, true);189183 input_sync(input);190184}191185
···88 * the Free Software Foundation.99 */10101111+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt1212+1113#define EVDEV_MINOR_BASE 641214#define EVDEV_MINORS 321315#define EVDEV_MIN_BUFFER_SIZE 64U···524522 if (type == EV_KEY && size == OLD_KEY_MAX) {525523 len = OLD_KEY_MAX;526524 if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000))527527- printk(KERN_WARNING528528- "evdev.c(EVIOCGBIT): Suspicious buffer size %u, "529529- "limiting output to %zu bytes. See "530530- "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n",531531- OLD_KEY_MAX,532532- BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long));525525+ pr_warning("(EVIOCGBIT): Suspicious buffer size %u, "526526+ "limiting output to %zu bytes. See "527527+ "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n",528528+ OLD_KEY_MAX,529529+ BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long));533530 }534531535532 return bits_to_user(bits, len, size, p, compat_mode);···686685 /* Now check variable-length commands */687686#define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))688687 switch (EVIOC_MASK_SIZE(cmd)) {688688+689689+ case EVIOCGPROP(0):690690+ return bits_to_user(dev->propbit, INPUT_PROP_MAX,691691+ size, p, compat_mode);689692690693 case EVIOCGKEY(0):691694 return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode);···902897 break;903898904899 if (minor == EVDEV_MINORS) {905905- printk(KERN_ERR "evdev: no more free evdev devices\n");900900+ pr_err("no more free evdev devices\n");906901 return -ENFILE;907902 }908903
+5-6
drivers/input/ff-core.c
···23232424/* #define DEBUG */25252626-#define debug(format, arg...) pr_debug("ff-core: " format "\n", ## arg)2626+#define pr_fmt(fmt) KBUILD_BASENAME ": " fmt27272828#include <linux/input.h>2929#include <linux/module.h>···116116117117 if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX ||118118 !test_bit(effect->type, dev->ffbit)) {119119- debug("invalid or not supported effect type in upload");119119+ pr_debug("invalid or not supported effect type in upload\n");120120 return -EINVAL;121121 }122122···124124 (effect->u.periodic.waveform < FF_WAVEFORM_MIN ||125125 effect->u.periodic.waveform > FF_WAVEFORM_MAX ||126126 !test_bit(effect->u.periodic.waveform, dev->ffbit))) {127127- debug("invalid or not supported wave form in upload");127127+ pr_debug("invalid or not supported wave form in upload\n");128128 return -EINVAL;129129 }130130···246246 struct ff_device *ff = dev->ff;247247 int i;248248249249- debug("flushing now");249249+ pr_debug("flushing now\n");250250251251 mutex_lock(&ff->mutex);252252···315315 int i;316316317317 if (!max_effects) {318318- printk(KERN_ERR319319- "ff-core: cannot allocate device without any effects\n");318318+ pr_err("cannot allocate device without any effects\n");320319 return -EINVAL;321320 }322321
···1818#include <linux/ioport.h>1919#include <linux/init.h>2020#include <linux/gameport.h>2121-#include <linux/wait.h>2221#include <linux/slab.h>2322#include <linux/delay.h>2424-#include <linux/kthread.h>2323+#include <linux/workqueue.h>2524#include <linux/sched.h> /* HZ */2625#include <linux/mutex.h>2727-#include <linux/freezer.h>28262927/*#include <asm/io.h>*/3028···232234233235static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */234236static LIST_HEAD(gameport_event_list);235235-static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);236236-static struct task_struct *gameport_task;237237238238-static int gameport_queue_event(void *object, struct module *owner,239239- enum gameport_event_type event_type)238238+static struct gameport_event *gameport_get_event(void)240239{240240+ struct gameport_event *event = NULL;241241 unsigned long flags;242242- struct gameport_event *event;243243- int retval = 0;244242245243 spin_lock_irqsave(&gameport_event_lock, flags);246244247247- /*248248- * Scan event list for the other events for the same gameport port,249249- * starting with the most recent one. If event is the same we250250- * do not need add new one. If event is of different type we251251- * need to add this event and should not look further because252252- * we need to preseve sequence of distinct events.253253- */254254- list_for_each_entry_reverse(event, &gameport_event_list, node) {255255- if (event->object == object) {256256- if (event->type == event_type)257257- goto out;258258- break;259259- }245245+ if (!list_empty(&gameport_event_list)) {246246+ event = list_first_entry(&gameport_event_list,247247+ struct gameport_event, node);248248+ list_del_init(&event->node);260249 }261250262262- event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);263263- if (!event) {264264- pr_err("Not enough memory to queue event %d\n", event_type);265265- retval = -ENOMEM;266266- goto out;267267- }268268-269269- if (!try_module_get(owner)) {270270- pr_warning("Can't get module reference, dropping event %d\n",271271- event_type);272272- kfree(event);273273- retval = -EINVAL;274274- goto out;275275- }276276-277277- event->type = event_type;278278- event->object = object;279279- event->owner = owner;280280-281281- list_add_tail(&event->node, &gameport_event_list);282282- wake_up(&gameport_wait);283283-284284-out:285251 spin_unlock_irqrestore(&gameport_event_lock, flags);286286- return retval;252252+ return event;287253}288254289255static void gameport_free_event(struct gameport_event *event)···281319 spin_unlock_irqrestore(&gameport_event_lock, flags);282320}283321284284-static struct gameport_event *gameport_get_event(void)285285-{286286- struct gameport_event *event = NULL;287287- unsigned long flags;288322289289- spin_lock_irqsave(&gameport_event_lock, flags);290290-291291- if (!list_empty(&gameport_event_list)) {292292- event = list_first_entry(&gameport_event_list,293293- struct gameport_event, node);294294- list_del_init(&event->node);295295- }296296-297297- spin_unlock_irqrestore(&gameport_event_lock, flags);298298- return event;299299-}300300-301301-static void gameport_handle_event(void)323323+static void gameport_handle_events(struct work_struct *work)302324{303325 struct gameport_event *event;304326···312366 }313367314368 mutex_unlock(&gameport_mutex);369369+}370370+371371+static DECLARE_WORK(gameport_event_work, gameport_handle_events);372372+373373+static int gameport_queue_event(void *object, struct module *owner,374374+ enum gameport_event_type event_type)375375+{376376+ unsigned long flags;377377+ struct gameport_event *event;378378+ int retval = 0;379379+380380+ spin_lock_irqsave(&gameport_event_lock, flags);381381+382382+ /*383383+ * Scan event list for the other events for the same gameport port,384384+ * starting with the most recent one. If event is the same we385385+ * do not need add new one. If event is of different type we386386+ * need to add this event and should not look further because387387+ * we need to preserve sequence of distinct events.388388+ */389389+ list_for_each_entry_reverse(event, &gameport_event_list, node) {390390+ if (event->object == object) {391391+ if (event->type == event_type)392392+ goto out;393393+ break;394394+ }395395+ }396396+397397+ event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);398398+ if (!event) {399399+ pr_err("Not enough memory to queue event %d\n", event_type);400400+ retval = -ENOMEM;401401+ goto out;402402+ }403403+404404+ if (!try_module_get(owner)) {405405+ pr_warning("Can't get module reference, dropping event %d\n",406406+ event_type);407407+ kfree(event);408408+ retval = -EINVAL;409409+ goto out;410410+ }411411+412412+ event->type = event_type;413413+ event->object = object;414414+ event->owner = owner;415415+416416+ list_add_tail(&event->node, &gameport_event_list);417417+ schedule_work(&gameport_event_work);418418+419419+out:420420+ spin_unlock_irqrestore(&gameport_event_lock, flags);421421+ return retval;315422}316423317424/*···417418 spin_unlock_irqrestore(&gameport_event_lock, flags);418419 return child;419420}420420-421421-static int gameport_thread(void *nothing)422422-{423423- set_freezable();424424- do {425425- gameport_handle_event();426426- wait_event_freezable(gameport_wait,427427- kthread_should_stop() || !list_empty(&gameport_event_list));428428- } while (!kthread_should_stop());429429-430430- return 0;431431-}432432-433421434422/*435423 * Gameport port operations···800814 return error;801815 }802816803803- gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");804804- if (IS_ERR(gameport_task)) {805805- bus_unregister(&gameport_bus);806806- error = PTR_ERR(gameport_task);807807- pr_err("Failed to start kgameportd, error: %d\n", error);808808- return error;809809- }810817811818 return 0;812819}···807828static void __exit gameport_exit(void)808829{809830 bus_unregister(&gameport_bus);810810- kthread_stop(gameport_task);831831+832832+ /*833833+ * There should not be any outstanding events but work may834834+ * still be scheduled so simply cancel it.835835+ */836836+ cancel_work_sync(&gameport_event_work);811837}812838813839subsys_initcall(gameport_init);
+170
drivers/input/input-mt.c
···11+/*22+ * Input Multitouch Library33+ *44+ * Copyright (c) 2008-2010 Henrik Rydberg55+ *66+ * This program is free software; you can redistribute it and/or modify it77+ * under the terms of the GNU General Public License version 2 as published by88+ * the Free Software Foundation.99+ */1010+1111+#include <linux/input/mt.h>1212+#include <linux/slab.h>1313+1414+#define TRKID_SGN ((TRKID_MAX + 1) >> 1)1515+1616+/**1717+ * input_mt_init_slots() - initialize MT input slots1818+ * @dev: input device supporting MT events and finger tracking1919+ * @num_slots: number of slots used by the device2020+ *2121+ * This function allocates all necessary memory for MT slot handling2222+ * in the input device, prepares the ABS_MT_SLOT and2323+ * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.2424+ * May be called repeatedly. Returns -EINVAL if attempting to2525+ * reinitialize with a different number of slots.2626+ */2727+int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)2828+{2929+ int i;3030+3131+ if (!num_slots)3232+ return 0;3333+ if (dev->mt)3434+ return dev->mtsize != num_slots ? -EINVAL : 0;3535+3636+ dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);3737+ if (!dev->mt)3838+ return -ENOMEM;3939+4040+ dev->mtsize = num_slots;4141+ input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);4242+ input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);4343+ input_set_events_per_packet(dev, 6 * num_slots);4444+4545+ /* Mark slots as 'unused' */4646+ for (i = 0; i < num_slots; i++)4747+ input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1);4848+4949+ return 0;5050+}5151+EXPORT_SYMBOL(input_mt_init_slots);5252+5353+/**5454+ * input_mt_destroy_slots() - frees the MT slots of the input device5555+ * @dev: input device with allocated MT slots5656+ *5757+ * This function is only needed in error path as the input core will5858+ * automatically free the MT slots when the device is destroyed.5959+ */6060+void input_mt_destroy_slots(struct input_dev *dev)6161+{6262+ kfree(dev->mt);6363+ dev->mt = NULL;6464+ dev->mtsize = 0;6565+ dev->slot = 0;6666+ dev->trkid = 0;6767+}6868+EXPORT_SYMBOL(input_mt_destroy_slots);6969+7070+/**7171+ * input_mt_report_slot_state() - report contact state7272+ * @dev: input device with allocated MT slots7373+ * @tool_type: the tool type to use in this slot7474+ * @active: true if contact is active, false otherwise7575+ *7676+ * Reports a contact via ABS_MT_TRACKING_ID, and optionally7777+ * ABS_MT_TOOL_TYPE. If active is true and the slot is currently7878+ * inactive, or if the tool type is changed, a new tracking id is7979+ * assigned to the slot. The tool type is only reported if the8080+ * corresponding absbit field is set.8181+ */8282+void input_mt_report_slot_state(struct input_dev *dev,8383+ unsigned int tool_type, bool active)8484+{8585+ struct input_mt_slot *mt;8686+ int id;8787+8888+ if (!dev->mt || !active) {8989+ input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);9090+ return;9191+ }9292+9393+ mt = &dev->mt[dev->slot];9494+ id = input_mt_get_value(mt, ABS_MT_TRACKING_ID);9595+ if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type)9696+ id = input_mt_new_trkid(dev);9797+9898+ input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);9999+ input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);100100+}101101+EXPORT_SYMBOL(input_mt_report_slot_state);102102+103103+/**104104+ * input_mt_report_finger_count() - report contact count105105+ * @dev: input device with allocated MT slots106106+ * @count: the number of contacts107107+ *108108+ * Reports the contact count via BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP,109109+ * BTN_TOOL_TRIPLETAP and BTN_TOOL_QUADTAP.110110+ *111111+ * The input core ensures only the KEY events already setup for112112+ * this device will produce output.113113+ */114114+void input_mt_report_finger_count(struct input_dev *dev, int count)115115+{116116+ input_event(dev, EV_KEY, BTN_TOOL_FINGER, count == 1);117117+ input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2);118118+ input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3);119119+ input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4);120120+}121121+EXPORT_SYMBOL(input_mt_report_finger_count);122122+123123+/**124124+ * input_mt_report_pointer_emulation() - common pointer emulation125125+ * @dev: input device with allocated MT slots126126+ * @use_count: report number of active contacts as finger count127127+ *128128+ * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and129129+ * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.130130+ *131131+ * The input core ensures only the KEY and ABS axes already setup for132132+ * this device will produce output.133133+ */134134+void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)135135+{136136+ struct input_mt_slot *oldest = 0;137137+ int oldid = dev->trkid;138138+ int count = 0;139139+ int i;140140+141141+ for (i = 0; i < dev->mtsize; ++i) {142142+ struct input_mt_slot *ps = &dev->mt[i];143143+ int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);144144+145145+ if (id < 0)146146+ continue;147147+ if ((id - oldid) & TRKID_SGN) {148148+ oldest = ps;149149+ oldid = id;150150+ }151151+ count++;152152+ }153153+154154+ input_event(dev, EV_KEY, BTN_TOUCH, count > 0);155155+ if (use_count)156156+ input_mt_report_finger_count(dev, count);157157+158158+ if (oldest) {159159+ int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);160160+ int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y);161161+ int p = input_mt_get_value(oldest, ABS_MT_PRESSURE);162162+163163+ input_event(dev, EV_ABS, ABS_X, x);164164+ input_event(dev, EV_ABS, ABS_Y, y);165165+ input_event(dev, EV_ABS, ABS_PRESSURE, p);166166+ } else {167167+ input_event(dev, EV_ABS, ABS_PRESSURE, 0);168168+ }169169+}170170+EXPORT_SYMBOL(input_mt_report_pointer_emulation);
+3-2
drivers/input/input-polldev.c
···88 * the Free Software Foundation.99 */10101111+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt1212+1113#include <linux/jiffies.h>1214#include <linux/slab.h>1315#include <linux/mutex.h>···3533 if (!polldev_users) {3634 polldev_wq = create_singlethread_workqueue("ipolldevd");3735 if (!polldev_wq) {3838- printk(KERN_ERR "input-polldev: failed to create "3939- "ipolldevd workqueue\n");3636+ pr_err("failed to create ipolldevd workqueue\n");4037 retval = -ENOMEM;4138 goto out;4239 }
+32-59
drivers/input/input.c
···1010 * the Free Software Foundation.1111 */12121313+#define pr_fmt(fmt) KBUILD_BASENAME ": " fmt1414+1315#include <linux/init.h>1416#include <linux/types.h>1515-#include <linux/input.h>1717+#include <linux/input/mt.h>1618#include <linux/module.h>1719#include <linux/slab.h>1820#include <linux/random.h>···961959962960 error = handler->connect(handler, dev, id);963961 if (error && error != -ENODEV)964964- printk(KERN_ERR965965- "input: failed to attach handler %s to device %s, "966966- "error: %d\n",967967- handler->name, kobject_name(&dev->dev.kobj), error);962962+ pr_err("failed to attach handler %s to device %s, error: %d\n",963963+ handler->name, kobject_name(&dev->dev.kobj), error);968964969965 return error;970966}···11091109 list_for_each_entry(handle, &dev->h_list, d_node)11101110 seq_printf(seq, "%s ", handle->name);11111111 seq_putc(seq, '\n');11121112+11131113+ input_seq_print_bitmap(seq, "PROP", dev->propbit, INPUT_PROP_MAX);1112111411131115 input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX);11141116 if (test_bit(EV_KEY, dev->evbit))···13351333}13361334static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);1337133513361336+static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,13371337+ int max, int add_cr);13381338+13391339+static ssize_t input_dev_show_properties(struct device *dev,13401340+ struct device_attribute *attr,13411341+ char *buf)13421342+{13431343+ struct input_dev *input_dev = to_input_dev(dev);13441344+ int len = input_print_bitmap(buf, PAGE_SIZE, input_dev->propbit,13451345+ INPUT_PROP_MAX, true);13461346+ return min_t(int, len, PAGE_SIZE);13471347+}13481348+static DEVICE_ATTR(properties, S_IRUGO, input_dev_show_properties, NULL);13491349+13381350static struct attribute *input_dev_attrs[] = {13391351 &dev_attr_name.attr,13401352 &dev_attr_phys.attr,13411353 &dev_attr_uniq.attr,13421354 &dev_attr_modalias.attr,13551355+ &dev_attr_properties.attr,13431356 NULL13441357};13451358···14881471{14891472 int len;1490147314911491- if (add_uevent_var(env, "%s=", name))14741474+ if (add_uevent_var(env, "%s", name))14921475 return -ENOMEM;1493147614941477 len = input_print_bitmap(&env->buf[env->buflen - 1],···15531536 INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys);15541537 if (dev->uniq)15551538 INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq);15391539+15401540+ INPUT_ADD_HOTPLUG_BM_VAR("PROP=", dev->propbit, INPUT_PROP_MAX);1556154115571542 INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX);15581543 if (test_bit(EV_KEY, dev->evbit))···17451726EXPORT_SYMBOL(input_free_device);1746172717471728/**17481748- * input_mt_create_slots() - create MT input slots17491749- * @dev: input device supporting MT events and finger tracking17501750- * @num_slots: number of slots used by the device17511751- *17521752- * This function allocates all necessary memory for MT slot handling in the17531753- * input device, and adds ABS_MT_SLOT to the device capabilities. All slots17541754- * are initially marked as unused by setting ABS_MT_TRACKING_ID to -1.17551755- */17561756-int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)17571757-{17581758- int i;17591759-17601760- if (!num_slots)17611761- return 0;17621762-17631763- dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);17641764- if (!dev->mt)17651765- return -ENOMEM;17661766-17671767- dev->mtsize = num_slots;17681768- input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);17691769-17701770- /* Mark slots as 'unused' */17711771- for (i = 0; i < num_slots; i++)17721772- dev->mt[i].abs[ABS_MT_TRACKING_ID - ABS_MT_FIRST] = -1;17731773-17741774- return 0;17751775-}17761776-EXPORT_SYMBOL(input_mt_create_slots);17771777-17781778-/**17791779- * input_mt_destroy_slots() - frees the MT slots of the input device17801780- * @dev: input device with allocated MT slots17811781- *17821782- * This function is only needed in error path as the input core will17831783- * automatically free the MT slots when the device is destroyed.17841784- */17851785-void input_mt_destroy_slots(struct input_dev *dev)17861786-{17871787- kfree(dev->mt);17881788- dev->mt = NULL;17891789- dev->mtsize = 0;17901790-}17911791-EXPORT_SYMBOL(input_mt_destroy_slots);17921792-17931793-/**17941729 * input_set_capability - mark device as capable of a certain event17951730 * @dev: device that is capable of emitting or accepting event17961731 * @type: type of the event (EV_KEY, EV_REL, etc...)···17931820 break;1794182117951822 default:17961796- printk(KERN_ERR17971797- "input_set_capability: unknown type %u (code %u)\n",17981798- type, code);18231823+ pr_err("input_set_capability: unknown type %u (code %u)\n",18241824+ type, code);17991825 dump_stack();18001826 return;18011827 }···18761904 return error;1877190518781906 path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);18791879- printk(KERN_INFO "input: %s as %s\n",18801880- dev->name ? dev->name : "Unspecified device", path ? path : "N/A");19071907+ pr_info("%s as %s\n",19081908+ dev->name ? dev->name : "Unspecified device",19091909+ path ? path : "N/A");18811910 kfree(path);1882191118831912 error = mutex_lock_interruptible(&input_mutex);···2160218721612188 err = class_register(&input_class);21622189 if (err) {21632163- printk(KERN_ERR "input: unable to register input_dev class\n");21902190+ pr_err("unable to register input_dev class\n");21642191 return err;21652192 }21662193···2170219721712198 err = register_chrdev(INPUT_MAJOR, "input", &input_fops);21722199 if (err) {21732173- printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);22002200+ pr_err("unable to register char major %d", INPUT_MAJOR);21742201 goto fail2;21752202 }21762203
+3-1
drivers/input/joydev.c
···1010 * (at your option) any later version.1111 */12121313+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt1414+1315#include <asm/io.h>1416#include <asm/system.h>1517#include <linux/delay.h>···808806 break;809807810808 if (minor == JOYDEV_MINORS) {811811- printk(KERN_ERR "joydev: no more free joydev devices\n");809809+ pr_err("no more free joydev devices\n");812810 return -ENFILE;813811 }814812
···543543static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)544544{545545 struct usb_endpoint_descriptor *ep_irq_out;546546- int error = -ENOMEM;546546+ int error;547547548548 if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)549549 return 0;550550551551 xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,552552 GFP_KERNEL, &xpad->odata_dma);553553- if (!xpad->odata)553553+ if (!xpad->odata) {554554+ error = -ENOMEM;554555 goto fail1;556556+ }555557556558 mutex_init(&xpad->odata_mutex);557559558560 xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);559559- if (!xpad->irq_out)561561+ if (!xpad->irq_out) {562562+ error = -ENOMEM;560563 goto fail2;564564+ }561565562566 ep_irq_out = &intf->cur_altsetting->endpoint[1].desc;563567 usb_fill_int_urb(xpad->irq_out, xpad->udev,···732728733729 if (xpad_led) {734730 led_classdev_unregister(&xpad_led->led_cdev);735735- kfree(xpad_led->name);731731+ kfree(xpad_led);736732 }737733}738734#else···760756{761757 struct usb_xpad *xpad = input_get_drvdata(dev);762758763763- if(xpad->xtype != XTYPE_XBOX360W)759759+ if (xpad->xtype != XTYPE_XBOX360W)764760 usb_kill_urb(xpad->irq_in);761761+765762 xpad_stop_output(xpad);766763}767764···794789 struct usb_xpad *xpad;795790 struct input_dev *input_dev;796791 struct usb_endpoint_descriptor *ep_irq_in;797797- int i;798798- int error = -ENOMEM;792792+ int i, error;799793800794 for (i = 0; xpad_device[i].idVendor; i++) {801795 if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&···804800805801 xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);806802 input_dev = input_allocate_device();807807- if (!xpad || !input_dev)803803+ if (!xpad || !input_dev) {804804+ error = -ENOMEM;808805 goto fail1;806806+ }809807810808 xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,811809 GFP_KERNEL, &xpad->idata_dma);812812- if (!xpad->idata)810810+ if (!xpad->idata) {811811+ error = -ENOMEM;813812 goto fail1;813813+ }814814815815 xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);816816- if (!xpad->irq_in)816816+ if (!xpad->irq_in) {817817+ error = -ENOMEM;817818 goto fail2;819819+ }818820819821 xpad->udev = udev;820822 xpad->mapping = xpad_device[i].mapping;···897887898888 error = xpad_init_output(intf, xpad);899889 if (error)900900- goto fail2;890890+ goto fail3;901891902892 error = xpad_init_ff(xpad);903893 if (error)904904- goto fail3;894894+ goto fail4;905895906896 error = xpad_led_probe(xpad);907897 if (error)908908- goto fail3;898898+ goto fail5;909899910900 ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;911901 usb_fill_int_urb(xpad->irq_in, udev,···917907918908 error = input_register_device(xpad->dev);919909 if (error)920920- goto fail4;910910+ goto fail6;921911922912 usb_set_intfdata(intf, xpad);923913924924- /*925925- * Submit the int URB immediatly rather than waiting for open926926- * because we get status messages from the device whether927927- * or not any controllers are attached. In fact, it's928928- * exactly the message that a controller has arrived that929929- * we're waiting for.930930- */931914 if (xpad->xtype == XTYPE_XBOX360W) {932932- xpad->irq_in->dev = xpad->udev;933933- error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);934934- if (error)935935- goto fail4;936936-937915 /*938916 * Setup the message to set the LEDs on the939917 * controller when it shows up940918 */941919 xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL);942942- if(!xpad->bulk_out)943943- goto fail5;920920+ if (!xpad->bulk_out) {921921+ error = -ENOMEM;922922+ goto fail7;923923+ }944924945925 xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL);946946- if(!xpad->bdata)947947- goto fail6;926926+ if (!xpad->bdata) {927927+ error = -ENOMEM;928928+ goto fail8;929929+ }948930949931 xpad->bdata[2] = 0x08;950932 switch (intf->cur_altsetting->desc.bInterfaceNumber) {···957955 usb_fill_bulk_urb(xpad->bulk_out, udev,958956 usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress),959957 xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad);958958+959959+ /*960960+ * Submit the int URB immediately rather than waiting for open961961+ * because we get status messages from the device whether962962+ * or not any controllers are attached. In fact, it's963963+ * exactly the message that a controller has arrived that964964+ * we're waiting for.965965+ */966966+ xpad->irq_in->dev = xpad->udev;967967+ error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);968968+ if (error)969969+ goto fail9;960970 }961971962972 return 0;963973964964- fail6: usb_free_urb(xpad->bulk_out);965965- fail5: usb_kill_urb(xpad->irq_in);966966- fail4: usb_free_urb(xpad->irq_in);967967- fail3: xpad_deinit_output(xpad);974974+ fail9: kfree(xpad->bdata);975975+ fail8: usb_free_urb(xpad->bulk_out);976976+ fail7: input_unregister_device(input_dev);977977+ input_dev = NULL;978978+ fail6: xpad_led_disconnect(xpad);979979+ fail5: if (input_dev)980980+ input_ff_destroy(input_dev);981981+ fail4: xpad_deinit_output(xpad);982982+ fail3: usb_free_urb(xpad->irq_in);968983 fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);969984 fail1: input_free_device(input_dev);970985 kfree(xpad);···993974{994975 struct usb_xpad *xpad = usb_get_intfdata (intf);995976996996- usb_set_intfdata(intf, NULL);997997- if (xpad) {998998- xpad_led_disconnect(xpad);999999- input_unregister_device(xpad->dev);10001000- xpad_deinit_output(xpad);10011001- if (xpad->xtype == XTYPE_XBOX360W) {10021002- usb_kill_urb(xpad->bulk_out);10031003- usb_free_urb(xpad->bulk_out);10041004- usb_kill_urb(xpad->irq_in);10051005- }10061006- usb_free_urb(xpad->irq_in);10071007- usb_free_coherent(xpad->udev, XPAD_PKT_LEN,10081008- xpad->idata, xpad->idata_dma);10091009- kfree(xpad);977977+ xpad_led_disconnect(xpad);978978+ input_unregister_device(xpad->dev);979979+ xpad_deinit_output(xpad);980980+981981+ if (xpad->xtype == XTYPE_XBOX360W) {982982+ usb_kill_urb(xpad->bulk_out);983983+ usb_free_urb(xpad->bulk_out);984984+ usb_kill_urb(xpad->irq_in);1010985 }986986+987987+ usb_free_urb(xpad->irq_in);988988+ usb_free_coherent(xpad->udev, XPAD_PKT_LEN,989989+ xpad->idata, xpad->idata_dma);990990+991991+ kfree(xpad->bdata);992992+ kfree(xpad);993993+994994+ usb_set_intfdata(intf, NULL);1011995}10129961013997static struct usb_driver xpad_driver = {···1022100010231001static int __init usb_xpad_init(void)10241002{10251025- int result = usb_register(&xpad_driver);10261026- if (result == 0)10271027- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");10281028- return result;10031003+ return usb_register(&xpad_driver);10291004}1030100510311006static void __exit usb_xpad_exit(void)
+15-4
drivers/input/keyboard/Kconfig
···196196 module will be called gpio_keys_polled.197197198198config KEYBOARD_TCA6416199199- tristate "TCA6416 Keypad Support"199199+ tristate "TCA6416/TCA6408A Keypad Support"200200 depends on I2C201201 help202202 This driver implements basic keypad functionality203203- for keys connected through TCA6416 IO expander203203+ for keys connected through TCA6416/TCA6408A IO expanders.204204205205 Say Y here if your device has keys connected to206206- TCA6416 IO expander. Your board-specific setup logic206206+ TCA6416/TCA6408A IO expander. Your board-specific setup logic207207 must also provide pin-mask details(of which TCA6416 pins208208 are used for keypad).209209210210- If enabled the complete TCA6416 device will be managed through210210+ If enabled the entire TCA6416 device will be managed through211211 this driver.212212213213+ To compile this driver as a module, choose M here: the214214+ module will be called tca6416_keypad.213215214216config KEYBOARD_MATRIX215217 tristate "GPIO driven matrix keypad support"···460458461459 To compile this driver as a module, choose M here: the462460 module will be called omap4-keypad.461461+462462+config KEYBOARD_SPEAR463463+ tristate "ST SPEAR keyboard support"464464+ depends on PLAT_SPEAR465465+ help466466+ Say Y here if you want to use the SPEAR keyboard.467467+468468+ To compile this driver as a module, choose M here: the469469+ module will be called spear-keboard.463470464471config KEYBOARD_TNETV107X465472 tristate "TI TNETV107X keypad support"
···448448 To compile this driver as a module, choose M here: the449449 module will be called adxl34x-spi.450450451451+config INPUT_CMA3000452452+ tristate "VTI CMA3000 Tri-axis accelerometer"453453+ help454454+ Say Y here if you want to use VTI CMA3000_D0x Accelerometer455455+ driver456456+457457+ This driver currently only supports I2C interface to the458458+ controller. Also select the I2C method.459459+460460+ If unsure, say N461461+462462+ To compile this driver as a module, choose M here: the463463+ module will be called cma3000_d0x.464464+465465+config INPUT_CMA3000_I2C466466+ tristate "Support I2C bus connection"467467+ depends on INPUT_CMA3000 && I2C468468+ help469469+ Say Y here if you want to use VTI CMA3000_D0x Accelerometer470470+ through I2C interface.471471+472472+ To compile this driver as a module, choose M here: the473473+ module will be called cma3000_d0x_i2c.474474+451475endif
···11+/*22+ * VTI CMA3000_D0x Accelerometer driver33+ *44+ * Copyright (C) 2010 Texas Instruments55+ * Author: Hemanth V <hemanthv@ti.com>66+ *77+ * This program is free software; you can redistribute it and/or modify it88+ * under the terms of the GNU General Public License version 2 as published by99+ * the Free Software Foundation.1010+ *1111+ * This program is distributed in the hope that it will be useful, but WITHOUT1212+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1313+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1414+ * more details.1515+ *1616+ * You should have received a copy of the GNU General Public License along with1717+ * this program. If not, see <http://www.gnu.org/licenses/>.1818+ */1919+2020+#include <linux/types.h>2121+#include <linux/interrupt.h>2222+#include <linux/delay.h>2323+#include <linux/slab.h>2424+#include <linux/input.h>2525+#include <linux/input/cma3000.h>2626+2727+#include "cma3000_d0x.h"2828+2929+#define CMA3000_WHOAMI 0x003030+#define CMA3000_REVID 0x013131+#define CMA3000_CTRL 0x023232+#define CMA3000_STATUS 0x033333+#define CMA3000_RSTR 0x043434+#define CMA3000_INTSTATUS 0x053535+#define CMA3000_DOUTX 0x063636+#define CMA3000_DOUTY 0x073737+#define CMA3000_DOUTZ 0x083838+#define CMA3000_MDTHR 0x093939+#define CMA3000_MDFFTMR 0x0A4040+#define CMA3000_FFTHR 0x0B4141+4242+#define CMA3000_RANGE2G (1 << 7)4343+#define CMA3000_RANGE8G (0 << 7)4444+#define CMA3000_BUSI2C (0 << 4)4545+#define CMA3000_MODEMASK (7 << 1)4646+#define CMA3000_GRANGEMASK (1 << 7)4747+4848+#define CMA3000_STATUS_PERR 14949+#define CMA3000_INTSTATUS_FFDET (1 << 2)5050+5151+/* Settling time delay in ms */5252+#define CMA3000_SETDELAY 305353+5454+/* Delay for clearing interrupt in us */5555+#define CMA3000_INTDELAY 445656+5757+5858+/*5959+ * Bit weights in mg for bit 0, other bits need6060+ * multipy factor 2^n. Eight bit is the sign bit.6161+ */6262+#define BIT_TO_2G 186363+#define BIT_TO_8G 716464+6565+struct cma3000_accl_data {6666+ const struct cma3000_bus_ops *bus_ops;6767+ const struct cma3000_platform_data *pdata;6868+6969+ struct device *dev;7070+ struct input_dev *input_dev;7171+7272+ int bit_to_mg;7373+ int irq;7474+7575+ int g_range;7676+ u8 mode;7777+7878+ struct mutex mutex;7979+ bool opened;8080+ bool suspended;8181+};8282+8383+#define CMA3000_READ(data, reg, msg) \8484+ (data->bus_ops->read(data->dev, reg, msg))8585+#define CMA3000_SET(data, reg, val, msg) \8686+ ((data)->bus_ops->write(data->dev, reg, val, msg))8787+8888+/*8989+ * Conversion for each of the eight modes to g, depending9090+ * on G range i.e 2G or 8G. Some modes always operate in9191+ * 8G.9292+ */9393+9494+static int mode_to_mg[8][2] = {9595+ { 0, 0 },9696+ { BIT_TO_8G, BIT_TO_2G },9797+ { BIT_TO_8G, BIT_TO_2G },9898+ { BIT_TO_8G, BIT_TO_8G },9999+ { BIT_TO_8G, BIT_TO_8G },100100+ { BIT_TO_8G, BIT_TO_2G },101101+ { BIT_TO_8G, BIT_TO_2G },102102+ { 0, 0},103103+};104104+105105+static void decode_mg(struct cma3000_accl_data *data, int *datax,106106+ int *datay, int *dataz)107107+{108108+ /* Data in 2's complement, convert to mg */109109+ *datax = ((s8)*datax) * data->bit_to_mg;110110+ *datay = ((s8)*datay) * data->bit_to_mg;111111+ *dataz = ((s8)*dataz) * data->bit_to_mg;112112+}113113+114114+static irqreturn_t cma3000_thread_irq(int irq, void *dev_id)115115+{116116+ struct cma3000_accl_data *data = dev_id;117117+ int datax, datay, dataz;118118+ u8 ctrl, mode, range, intr_status;119119+120120+ intr_status = CMA3000_READ(data, CMA3000_INTSTATUS, "interrupt status");121121+ if (intr_status < 0)122122+ return IRQ_NONE;123123+124124+ /* Check if free fall is detected, report immediately */125125+ if (intr_status & CMA3000_INTSTATUS_FFDET) {126126+ input_report_abs(data->input_dev, ABS_MISC, 1);127127+ input_sync(data->input_dev);128128+ } else {129129+ input_report_abs(data->input_dev, ABS_MISC, 0);130130+ }131131+132132+ datax = CMA3000_READ(data, CMA3000_DOUTX, "X");133133+ datay = CMA3000_READ(data, CMA3000_DOUTY, "Y");134134+ dataz = CMA3000_READ(data, CMA3000_DOUTZ, "Z");135135+136136+ ctrl = CMA3000_READ(data, CMA3000_CTRL, "ctrl");137137+ mode = (ctrl & CMA3000_MODEMASK) >> 1;138138+ range = (ctrl & CMA3000_GRANGEMASK) >> 7;139139+140140+ data->bit_to_mg = mode_to_mg[mode][range];141141+142142+ /* Interrupt not for this device */143143+ if (data->bit_to_mg == 0)144144+ return IRQ_NONE;145145+146146+ /* Decode register values to milli g */147147+ decode_mg(data, &datax, &datay, &dataz);148148+149149+ input_report_abs(data->input_dev, ABS_X, datax);150150+ input_report_abs(data->input_dev, ABS_Y, datay);151151+ input_report_abs(data->input_dev, ABS_Z, dataz);152152+ input_sync(data->input_dev);153153+154154+ return IRQ_HANDLED;155155+}156156+157157+static int cma3000_reset(struct cma3000_accl_data *data)158158+{159159+ int val;160160+161161+ /* Reset sequence */162162+ CMA3000_SET(data, CMA3000_RSTR, 0x02, "Reset");163163+ CMA3000_SET(data, CMA3000_RSTR, 0x0A, "Reset");164164+ CMA3000_SET(data, CMA3000_RSTR, 0x04, "Reset");165165+166166+ /* Settling time delay */167167+ mdelay(10);168168+169169+ val = CMA3000_READ(data, CMA3000_STATUS, "Status");170170+ if (val < 0) {171171+ dev_err(data->dev, "Reset failed\n");172172+ return val;173173+ }174174+175175+ if (val & CMA3000_STATUS_PERR) {176176+ dev_err(data->dev, "Parity Error\n");177177+ return -EIO;178178+ }179179+180180+ return 0;181181+}182182+183183+static int cma3000_poweron(struct cma3000_accl_data *data)184184+{185185+ const struct cma3000_platform_data *pdata = data->pdata;186186+ u8 ctrl = 0;187187+ int ret;188188+189189+ if (data->g_range == CMARANGE_2G) {190190+ ctrl = (data->mode << 1) | CMA3000_RANGE2G;191191+ } else if (data->g_range == CMARANGE_8G) {192192+ ctrl = (data->mode << 1) | CMA3000_RANGE8G;193193+ } else {194194+ dev_info(data->dev,195195+ "Invalid G range specified, assuming 8G\n");196196+ ctrl = (data->mode << 1) | CMA3000_RANGE8G;197197+ }198198+199199+ ctrl |= data->bus_ops->ctrl_mod;200200+201201+ CMA3000_SET(data, CMA3000_MDTHR, pdata->mdthr,202202+ "Motion Detect Threshold");203203+ CMA3000_SET(data, CMA3000_MDFFTMR, pdata->mdfftmr,204204+ "Time register");205205+ CMA3000_SET(data, CMA3000_FFTHR, pdata->ffthr,206206+ "Free fall threshold");207207+ ret = CMA3000_SET(data, CMA3000_CTRL, ctrl, "Mode setting");208208+ if (ret < 0)209209+ return -EIO;210210+211211+ msleep(CMA3000_SETDELAY);212212+213213+ return 0;214214+}215215+216216+static int cma3000_poweroff(struct cma3000_accl_data *data)217217+{218218+ int ret;219219+220220+ ret = CMA3000_SET(data, CMA3000_CTRL, CMAMODE_POFF, "Mode setting");221221+ msleep(CMA3000_SETDELAY);222222+223223+ return ret;224224+}225225+226226+static int cma3000_open(struct input_dev *input_dev)227227+{228228+ struct cma3000_accl_data *data = input_get_drvdata(input_dev);229229+230230+ mutex_lock(&data->mutex);231231+232232+ if (!data->suspended)233233+ cma3000_poweron(data);234234+235235+ data->opened = true;236236+237237+ mutex_unlock(&data->mutex);238238+239239+ return 0;240240+}241241+242242+static void cma3000_close(struct input_dev *input_dev)243243+{244244+ struct cma3000_accl_data *data = input_get_drvdata(input_dev);245245+246246+ mutex_lock(&data->mutex);247247+248248+ if (!data->suspended)249249+ cma3000_poweroff(data);250250+251251+ data->opened = false;252252+253253+ mutex_unlock(&data->mutex);254254+}255255+256256+void cma3000_suspend(struct cma3000_accl_data *data)257257+{258258+ mutex_lock(&data->mutex);259259+260260+ if (!data->suspended && data->opened)261261+ cma3000_poweroff(data);262262+263263+ data->suspended = true;264264+265265+ mutex_unlock(&data->mutex);266266+}267267+EXPORT_SYMBOL(cma3000_suspend);268268+269269+270270+void cma3000_resume(struct cma3000_accl_data *data)271271+{272272+ mutex_lock(&data->mutex);273273+274274+ if (data->suspended && data->opened)275275+ cma3000_poweron(data);276276+277277+ data->suspended = false;278278+279279+ mutex_unlock(&data->mutex);280280+}281281+EXPORT_SYMBOL(cma3000_resume);282282+283283+struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,284284+ const struct cma3000_bus_ops *bops)285285+{286286+ const struct cma3000_platform_data *pdata = dev->platform_data;287287+ struct cma3000_accl_data *data;288288+ struct input_dev *input_dev;289289+ int rev;290290+ int error;291291+292292+ if (!pdata) {293293+ dev_err(dev, "platform data not found\n");294294+ error = -EINVAL;295295+ goto err_out;296296+ }297297+298298+299299+ /* if no IRQ return error */300300+ if (irq == 0) {301301+ error = -EINVAL;302302+ goto err_out;303303+ }304304+305305+ data = kzalloc(sizeof(struct cma3000_accl_data), GFP_KERNEL);306306+ input_dev = input_allocate_device();307307+ if (!data || !input_dev) {308308+ error = -ENOMEM;309309+ goto err_free_mem;310310+ }311311+312312+ data->dev = dev;313313+ data->input_dev = input_dev;314314+ data->bus_ops = bops;315315+ data->pdata = pdata;316316+ data->irq = irq;317317+ mutex_init(&data->mutex);318318+319319+ data->mode = pdata->mode;320320+ if (data->mode < CMAMODE_DEFAULT || data->mode > CMAMODE_POFF) {321321+ data->mode = CMAMODE_MOTDET;322322+ dev_warn(dev,323323+ "Invalid mode specified, assuming Motion Detect\n");324324+ }325325+326326+ data->g_range = pdata->g_range;327327+ if (data->g_range != CMARANGE_2G && data->g_range != CMARANGE_8G) {328328+ dev_info(dev,329329+ "Invalid G range specified, assuming 8G\n");330330+ data->g_range = CMARANGE_8G;331331+ }332332+333333+ input_dev->name = "cma3000-accelerometer";334334+ input_dev->id.bustype = bops->bustype;335335+ input_dev->open = cma3000_open;336336+ input_dev->close = cma3000_close;337337+338338+ __set_bit(EV_ABS, input_dev->evbit);339339+340340+ input_set_abs_params(input_dev, ABS_X,341341+ -data->g_range, data->g_range, pdata->fuzz_x, 0);342342+ input_set_abs_params(input_dev, ABS_Y,343343+ -data->g_range, data->g_range, pdata->fuzz_y, 0);344344+ input_set_abs_params(input_dev, ABS_Z,345345+ -data->g_range, data->g_range, pdata->fuzz_z, 0);346346+ input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);347347+348348+ input_set_drvdata(input_dev, data);349349+350350+ error = cma3000_reset(data);351351+ if (error)352352+ goto err_free_mem;353353+354354+ rev = CMA3000_READ(data, CMA3000_REVID, "Revid");355355+ if (rev < 0) {356356+ error = rev;357357+ goto err_free_mem;358358+ }359359+360360+ pr_info("CMA3000 Accelerometer: Revision %x\n", rev);361361+362362+ error = request_threaded_irq(irq, NULL, cma3000_thread_irq,363363+ pdata->irqflags | IRQF_ONESHOT,364364+ "cma3000_d0x", data);365365+ if (error) {366366+ dev_err(dev, "request_threaded_irq failed\n");367367+ goto err_free_mem;368368+ }369369+370370+ error = input_register_device(data->input_dev);371371+ if (error) {372372+ dev_err(dev, "Unable to register input device\n");373373+ goto err_free_irq;374374+ }375375+376376+ return data;377377+378378+err_free_irq:379379+ free_irq(irq, data);380380+err_free_mem:381381+ input_free_device(input_dev);382382+ kfree(data);383383+err_out:384384+ return ERR_PTR(error);385385+}386386+EXPORT_SYMBOL(cma3000_init);387387+388388+void cma3000_exit(struct cma3000_accl_data *data)389389+{390390+ free_irq(data->irq, data);391391+ input_unregister_device(data->input_dev);392392+ kfree(data);393393+}394394+EXPORT_SYMBOL(cma3000_exit);395395+396396+MODULE_DESCRIPTION("CMA3000-D0x Accelerometer Driver");397397+MODULE_LICENSE("GPL");398398+MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>");
+42
drivers/input/misc/cma3000_d0x.h
···11+/*22+ * VTI CMA3000_D0x Accelerometer driver33+ *44+ * Copyright (C) 2010 Texas Instruments55+ * Author: Hemanth V <hemanthv@ti.com>66+ *77+ * This program is free software; you can redistribute it and/or modify it88+ * under the terms of the GNU General Public License version 2 as published by99+ * the Free Software Foundation.1010+ *1111+ * This program is distributed in the hope that it will be useful, but WITHOUT1212+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1313+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1414+ * more details.1515+ *1616+ * You should have received a copy of the GNU General Public License along with1717+ * this program. If not, see <http://www.gnu.org/licenses/>.1818+ */1919+2020+#ifndef _INPUT_CMA3000_H2121+#define _INPUT_CMA3000_H2222+2323+#include <linux/types.h>2424+#include <linux/input.h>2525+2626+struct device;2727+struct cma3000_accl_data;2828+2929+struct cma3000_bus_ops {3030+ u16 bustype;3131+ u8 ctrl_mod;3232+ int (*read)(struct device *, u8, char *);3333+ int (*write)(struct device *, u8, u8, char *);3434+};3535+3636+struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,3737+ const struct cma3000_bus_ops *bops);3838+void cma3000_exit(struct cma3000_accl_data *);3939+void cma3000_suspend(struct cma3000_accl_data *);4040+void cma3000_resume(struct cma3000_accl_data *);4141+4242+#endif
+143
drivers/input/misc/cma3000_d0x_i2c.c
···11+/*22+ * Implements I2C interface for VTI CMA300_D0x Accelerometer driver33+ *44+ * Copyright (C) 2010 Texas Instruments55+ * Author: Hemanth V <hemanthv@ti.com>66+ *77+ * This program is free software; you can redistribute it and/or modify it88+ * under the terms of the GNU General Public License version 2 as published by99+ * the Free Software Foundation.1010+ *1111+ * This program is distributed in the hope that it will be useful, but WITHOUT1212+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1313+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1414+ * more details.1515+ *1616+ * You should have received a copy of the GNU General Public License along with1717+ * this program. If not, see <http://www.gnu.org/licenses/>.1818+ */1919+2020+#include <linux/module.h>2121+#include <linux/i2c.h>2222+#include <linux/input/cma3000.h>2323+#include "cma3000_d0x.h"2424+2525+static int cma3000_i2c_set(struct device *dev,2626+ u8 reg, u8 val, char *msg)2727+{2828+ struct i2c_client *client = to_i2c_client(dev);2929+ int ret;3030+3131+ ret = i2c_smbus_write_byte_data(client, reg, val);3232+ if (ret < 0)3333+ dev_err(&client->dev,3434+ "%s failed (%s, %d)\n", __func__, msg, ret);3535+ return ret;3636+}3737+3838+static int cma3000_i2c_read(struct device *dev, u8 reg, char *msg)3939+{4040+ struct i2c_client *client = to_i2c_client(dev);4141+ int ret;4242+4343+ ret = i2c_smbus_read_byte_data(client, reg);4444+ if (ret < 0)4545+ dev_err(&client->dev,4646+ "%s failed (%s, %d)\n", __func__, msg, ret);4747+ return ret;4848+}4949+5050+static const struct cma3000_bus_ops cma3000_i2c_bops = {5151+ .bustype = BUS_I2C,5252+#define CMA3000_BUSI2C (0 << 4)5353+ .ctrl_mod = CMA3000_BUSI2C,5454+ .read = cma3000_i2c_read,5555+ .write = cma3000_i2c_set,5656+};5757+5858+static int __devinit cma3000_i2c_probe(struct i2c_client *client,5959+ const struct i2c_device_id *id)6060+{6161+ struct cma3000_accl_data *data;6262+6363+ data = cma3000_init(&client->dev, client->irq, &cma3000_i2c_bops);6464+ if (IS_ERR(data))6565+ return PTR_ERR(data);6666+6767+ i2c_set_clientdata(client, data);6868+6969+ return 0;7070+}7171+7272+static int __devexit cma3000_i2c_remove(struct i2c_client *client)7373+{7474+ struct cma3000_accl_data *data = i2c_get_clientdata(client);7575+7676+ cma3000_exit(data);7777+7878+ return 0;7979+}8080+8181+#ifdef CONFIG_PM8282+static int cma3000_i2c_suspend(struct device *dev)8383+{8484+ struct i2c_client *client = to_i2c_client(dev);8585+ struct cma3000_accl_data *data = i2c_get_clientdata(client);8686+8787+ cma3000_suspend(data);8888+8989+ return 0;9090+}9191+9292+static int cma3000_i2c_resume(struct device *dev)9393+{9494+ struct i2c_client *client = to_i2c_client(dev);9595+ struct cma3000_accl_data *data = i2c_get_clientdata(client);9696+9797+ cma3000_resume(data);9898+9999+ return 0;100100+}101101+102102+static const struct dev_pm_ops cma3000_i2c_pm_ops = {103103+ .suspend = cma3000_i2c_suspend,104104+ .resume = cma3000_i2c_resume,105105+};106106+#endif107107+108108+static const struct i2c_device_id cma3000_i2c_id[] = {109109+ { "cma3000_d01", 0 },110110+ { },111111+};112112+113113+MODULE_DEVICE_TABLE(i2c, cma3000_i2c_id);114114+115115+static struct i2c_driver cma3000_i2c_driver = {116116+ .probe = cma3000_i2c_probe,117117+ .remove = __devexit_p(cma3000_i2c_remove),118118+ .id_table = cma3000_i2c_id,119119+ .driver = {120120+ .name = "cma3000_i2c_accl",121121+ .owner = THIS_MODULE,122122+#ifdef CONFIG_PM123123+ .pm = &cma3000_i2c_pm_ops,124124+#endif125125+ },126126+};127127+128128+static int __init cma3000_i2c_init(void)129129+{130130+ return i2c_add_driver(&cma3000_i2c_driver);131131+}132132+133133+static void __exit cma3000_i2c_exit(void)134134+{135135+ i2c_del_driver(&cma3000_i2c_driver);136136+}137137+138138+module_init(cma3000_i2c_init);139139+module_exit(cma3000_i2c_exit);140140+141141+MODULE_DESCRIPTION("CMA3000-D0x Accelerometer I2C Driver");142142+MODULE_LICENSE("GPL");143143+MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>");
···3737#include <linux/fs.h>3838#include <linux/miscdevice.h>3939#include <linux/uinput.h>4040+#include <linux/input/mt.h>4041#include "../input-compat.h"41424243static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)···407406 goto exit;408407 if (test_bit(ABS_MT_SLOT, dev->absbit)) {409408 int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;410410- input_mt_create_slots(dev, nslot);411411- input_set_events_per_packet(dev, 6 * nslot);409409+ input_mt_init_slots(dev, nslot);412410 } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {413411 input_set_events_per_packet(dev, 60);414412 }···678678679679 case UI_SET_SWBIT:680680 retval = uinput_set_bit(arg, swbit, SW_MAX);681681+ break;682682+683683+ case UI_SET_PROPBIT:684684+ retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX);681685 break;682686683687 case UI_SET_PHYS:
+613-80
drivers/input/mouse/hgpk.c
···4040#include "psmouse.h"4141#include "hgpk.h"42424343+#define ILLEGAL_XY 9999994444+4345static bool tpdebug;4446module_param(tpdebug, bool, 0644);4547MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");···4947static int recalib_delta = 100;5048module_param(recalib_delta, int, 0644);5149MODULE_PARM_DESC(recalib_delta,5252- "packets containing a delta this large will cause a recalibration.");5050+ "packets containing a delta this large will be discarded, and a "5151+ "recalibration may be scheduled.");53525454-static int jumpy_delay = 1000;5353+static int jumpy_delay = 20;5554module_param(jumpy_delay, int, 0644);5655MODULE_PARM_DESC(jumpy_delay,5756 "delay (ms) before recal after jumpiness detected");58575959-static int spew_delay = 1000;5858+static int spew_delay = 1;6059module_param(spew_delay, int, 0644);6160MODULE_PARM_DESC(spew_delay,6261 "delay (ms) before recal after packet spew detected");63626464-static int recal_guard_time = 2000;6363+static int recal_guard_time;6564module_param(recal_guard_time, int, 0644);6665MODULE_PARM_DESC(recal_guard_time,6766 "interval (ms) during which recal will be restarted if packet received");68676969-static int post_interrupt_delay = 1000;6868+static int post_interrupt_delay = 40;7069module_param(post_interrupt_delay, int, 0644);7170MODULE_PARM_DESC(post_interrupt_delay,7271 "delay (ms) before recal after recal interrupt detected");73727373+static bool autorecal = true;7474+module_param(autorecal, bool, 0644);7575+MODULE_PARM_DESC(autorecal, "enable recalibration in the driver");7676+7777+static char hgpk_mode_name[16];7878+module_param_string(hgpk_mode, hgpk_mode_name, sizeof(hgpk_mode_name), 0644);7979+MODULE_PARM_DESC(hgpk_mode,8080+ "default hgpk mode: mouse, glidesensor or pentablet");8181+8282+static int hgpk_default_mode = HGPK_MODE_MOUSE;8383+8484+static const char * const hgpk_mode_names[] = {8585+ [HGPK_MODE_MOUSE] = "Mouse",8686+ [HGPK_MODE_GLIDESENSOR] = "GlideSensor",8787+ [HGPK_MODE_PENTABLET] = "PenTablet",8888+};8989+9090+static int hgpk_mode_from_name(const char *buf, int len)9191+{9292+ int i;9393+9494+ for (i = 0; i < ARRAY_SIZE(hgpk_mode_names); i++) {9595+ const char *name = hgpk_mode_names[i];9696+ if (strlen(name) == len && !strncasecmp(name, buf, len))9797+ return i;9898+ }9999+100100+ return HGPK_MODE_INVALID;101101+}102102+74103/*7575- * When the touchpad gets ultra-sensitive, one can keep their finger 1/2"7676- * above the pad and still have it send packets. This causes a jump cursor7777- * when one places their finger on the pad. We can probably detect the7878- * jump as we see a large deltas (>= 100px). In mouse mode, I've been7979- * unable to even come close to 100px deltas during normal usage, so I think8080- * this threshold is safe. If a large delta occurs, trigger a recalibration.104104+ * see if new value is within 20% of half of old value81105 */8282-static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y)106106+static int approx_half(int curr, int prev)107107+{108108+ int belowhalf, abovehalf;109109+110110+ if (curr < 5 || prev < 5)111111+ return 0;112112+113113+ belowhalf = (prev * 8) / 20;114114+ abovehalf = (prev * 12) / 20;115115+116116+ return belowhalf < curr && curr <= abovehalf;117117+}118118+119119+/*120120+ * Throw out oddly large delta packets, and any that immediately follow whose121121+ * values are each approximately half of the previous. It seems that the ALPS122122+ * firmware emits errant packets, and they get averaged out slowly.123123+ */124124+static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y)83125{84126 struct hgpk_data *priv = psmouse->private;127127+ int avx, avy;128128+ bool do_recal = false;851298686- if (abs(x) > recalib_delta || abs(y) > recalib_delta) {8787- hgpk_err(psmouse, ">%dpx jump detected (%d,%d)\n",8888- recalib_delta, x, y);8989- /* My car gets forty rods to the hogshead and that's the9090- * way I likes it! */130130+ avx = abs(x);131131+ avy = abs(y);132132+133133+ /* discard if too big, or half that but > 4 times the prev delta */134134+ if (avx > recalib_delta ||135135+ (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) {136136+ hgpk_err(psmouse, "detected %dpx jump in x\n", x);137137+ priv->xbigj = avx;138138+ } else if (approx_half(avx, priv->xbigj)) {139139+ hgpk_err(psmouse, "detected secondary %dpx jump in x\n", x);140140+ priv->xbigj = avx;141141+ priv->xsaw_secondary++;142142+ } else {143143+ if (priv->xbigj && priv->xsaw_secondary > 1)144144+ do_recal = true;145145+ priv->xbigj = 0;146146+ priv->xsaw_secondary = 0;147147+ }148148+149149+ if (avy > recalib_delta ||150150+ (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) {151151+ hgpk_err(psmouse, "detected %dpx jump in y\n", y);152152+ priv->ybigj = avy;153153+ } else if (approx_half(avy, priv->ybigj)) {154154+ hgpk_err(psmouse, "detected secondary %dpx jump in y\n", y);155155+ priv->ybigj = avy;156156+ priv->ysaw_secondary++;157157+ } else {158158+ if (priv->ybigj && priv->ysaw_secondary > 1)159159+ do_recal = true;160160+ priv->ybigj = 0;161161+ priv->ysaw_secondary = 0;162162+ }163163+164164+ priv->xlast = avx;165165+ priv->ylast = avy;166166+167167+ if (do_recal && jumpy_delay) {168168+ hgpk_err(psmouse, "scheduling recalibration\n");91169 psmouse_queue_work(psmouse, &priv->recalib_wq,92170 msecs_to_jiffies(jumpy_delay));93171 }172172+173173+ return priv->xbigj || priv->ybigj;174174+}175175+176176+static void hgpk_reset_spew_detection(struct hgpk_data *priv)177177+{178178+ priv->spew_count = 0;179179+ priv->dupe_count = 0;180180+ priv->x_tally = 0;181181+ priv->y_tally = 0;182182+ priv->spew_flag = NO_SPEW;183183+}184184+185185+static void hgpk_reset_hack_state(struct psmouse *psmouse)186186+{187187+ struct hgpk_data *priv = psmouse->private;188188+189189+ priv->abs_x = priv->abs_y = -1;190190+ priv->xlast = priv->ylast = ILLEGAL_XY;191191+ priv->xbigj = priv->ybigj = 0;192192+ priv->xsaw_secondary = priv->ysaw_secondary = 0;193193+ hgpk_reset_spew_detection(priv);94194}9519596196/*···220116 if (l || r)221117 return;222118119119+ /* don't track spew if the workaround feature has been turned off */120120+ if (!spew_delay)121121+ return;122122+123123+ if (abs(x) > 3 || abs(y) > 3) {124124+ /* no spew, or spew ended */125125+ hgpk_reset_spew_detection(priv);126126+ return;127127+ }128128+129129+ /* Keep a tally of the overall delta to the cursor position caused by130130+ * the spew */223131 priv->x_tally += x;224132 priv->y_tally += y;225133226226- if (++priv->count > 100) {134134+ switch (priv->spew_flag) {135135+ case NO_SPEW:136136+ /* we're not spewing, but this packet might be the start */137137+ priv->spew_flag = MAYBE_SPEWING;138138+139139+ /* fall-through */140140+141141+ case MAYBE_SPEWING:142142+ priv->spew_count++;143143+144144+ if (priv->spew_count < SPEW_WATCH_COUNT)145145+ break;146146+147147+ /* excessive spew detected, request recalibration */148148+ priv->spew_flag = SPEW_DETECTED;149149+150150+ /* fall-through */151151+152152+ case SPEW_DETECTED:153153+ /* only recalibrate when the overall delta to the cursor154154+ * is really small. if the spew is causing significant cursor155155+ * movement, it is probably a case of the user moving the156156+ * cursor very slowly across the screen. */227157 if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) {228228- hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n",158158+ hgpk_err(psmouse, "packet spew detected (%d,%d)\n",229159 priv->x_tally, priv->y_tally);160160+ priv->spew_flag = RECALIBRATING;230161 psmouse_queue_work(psmouse, &priv->recalib_wq,231162 msecs_to_jiffies(spew_delay));232163 }233233- /* reset every 100 packets */234234- priv->count = 0;235235- priv->x_tally = 0;236236- priv->y_tally = 0;164164+165165+ break;166166+ case RECALIBRATING:167167+ /* we already detected a spew and requested a recalibration,168168+ * just wait for the queue to kick into action. */169169+ break;237170 }238171}239172···284143 * swr/swl are the left/right buttons.285144 * x-neg/y-neg are the x and y delta negative bits286145 * x-over/y-over are the x and y overflow bits146146+ *147147+ * ---148148+ *149149+ * HGPK Advanced Mode - single-mode format150150+ *151151+ * byte 0(PT): 1 1 0 0 1 1 1 1152152+ * byte 0(GS): 1 1 1 1 1 1 1 1153153+ * byte 1: 0 x6 x5 x4 x3 x2 x1 x0154154+ * byte 2(PT): 0 0 x9 x8 x7 ? pt-dsw 0155155+ * byte 2(GS): 0 x10 x9 x8 x7 ? gs-dsw pt-dsw156156+ * byte 3: 0 y9 y8 y7 1 0 swr swl157157+ * byte 4: 0 y6 y5 y4 y3 y2 y1 y0158158+ * byte 5: 0 z6 z5 z4 z3 z2 z1 z0159159+ *160160+ * ?'s are not defined in the protocol spec, may vary between models.161161+ *162162+ * swr/swl are the left/right buttons.163163+ *164164+ * pt-dsw/gs-dsw indicate that the pt/gs sensor is detecting a165165+ * pen/finger287166 */288288-static int hgpk_validate_byte(unsigned char *packet)167167+static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet)289168{290290- return (packet[0] & 0x0C) != 0x08;169169+ struct hgpk_data *priv = psmouse->private;170170+ int pktcnt = psmouse->pktcnt;171171+ bool valid;172172+173173+ switch (priv->mode) {174174+ case HGPK_MODE_MOUSE:175175+ valid = (packet[0] & 0x0C) == 0x08;176176+ break;177177+178178+ case HGPK_MODE_GLIDESENSOR:179179+ valid = pktcnt == 1 ?180180+ packet[0] == HGPK_GS : !(packet[pktcnt - 1] & 0x80);181181+ break;182182+183183+ case HGPK_MODE_PENTABLET:184184+ valid = pktcnt == 1 ?185185+ packet[0] == HGPK_PT : !(packet[pktcnt - 1] & 0x80);186186+ break;187187+188188+ default:189189+ valid = false;190190+ break;191191+ }192192+193193+ if (!valid)194194+ hgpk_dbg(psmouse,195195+ "bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n",196196+ priv->mode, pktcnt,197197+ psmouse->packet[0], psmouse->packet[1],198198+ psmouse->packet[2], psmouse->packet[3],199199+ psmouse->packet[4], psmouse->packet[5]);200200+201201+ return valid;291202}292203293293-static void hgpk_process_packet(struct psmouse *psmouse)204204+static void hgpk_process_advanced_packet(struct psmouse *psmouse)205205+{206206+ struct hgpk_data *priv = psmouse->private;207207+ struct input_dev *idev = psmouse->dev;208208+ unsigned char *packet = psmouse->packet;209209+ int down = !!(packet[2] & 2);210210+ int left = !!(packet[3] & 1);211211+ int right = !!(packet[3] & 2);212212+ int x = packet[1] | ((packet[2] & 0x78) << 4);213213+ int y = packet[4] | ((packet[3] & 0x70) << 3);214214+215215+ if (priv->mode == HGPK_MODE_GLIDESENSOR) {216216+ int pt_down = !!(packet[2] & 1);217217+ int finger_down = !!(packet[2] & 2);218218+ int z = packet[5];219219+220220+ input_report_abs(idev, ABS_PRESSURE, z);221221+ if (tpdebug)222222+ hgpk_dbg(psmouse, "pd=%d fd=%d z=%d",223223+ pt_down, finger_down, z);224224+ } else {225225+ /*226226+ * PenTablet mode does not report pressure, so we don't227227+ * report it here228228+ */229229+ if (tpdebug)230230+ hgpk_dbg(psmouse, "pd=%d ", down);231231+ }232232+233233+ if (tpdebug)234234+ hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y);235235+236236+ input_report_key(idev, BTN_TOUCH, down);237237+ input_report_key(idev, BTN_LEFT, left);238238+ input_report_key(idev, BTN_RIGHT, right);239239+240240+ /*241241+ * If this packet says that the finger was removed, reset our position242242+ * tracking so that we don't erroneously detect a jump on next press.243243+ */244244+ if (!down) {245245+ hgpk_reset_hack_state(psmouse);246246+ goto done;247247+ }248248+249249+ /*250250+ * Weed out duplicate packets (we get quite a few, and they mess up251251+ * our jump detection)252252+ */253253+ if (x == priv->abs_x && y == priv->abs_y) {254254+ if (++priv->dupe_count > SPEW_WATCH_COUNT) {255255+ if (tpdebug)256256+ hgpk_dbg(psmouse, "hard spew detected\n");257257+ priv->spew_flag = RECALIBRATING;258258+ psmouse_queue_work(psmouse, &priv->recalib_wq,259259+ msecs_to_jiffies(spew_delay));260260+ }261261+ goto done;262262+ }263263+264264+ /* not a duplicate, continue with position reporting */265265+ priv->dupe_count = 0;266266+267267+ /* Don't apply hacks in PT mode, it seems reliable */268268+ if (priv->mode != HGPK_MODE_PENTABLET && priv->abs_x != -1) {269269+ int x_diff = priv->abs_x - x;270270+ int y_diff = priv->abs_y - y;271271+ if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) {272272+ if (tpdebug)273273+ hgpk_dbg(psmouse, "discarding\n");274274+ goto done;275275+ }276276+ hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff);277277+ }278278+279279+ input_report_abs(idev, ABS_X, x);280280+ input_report_abs(idev, ABS_Y, y);281281+ priv->abs_x = x;282282+ priv->abs_y = y;283283+284284+done:285285+ input_sync(idev);286286+}287287+288288+static void hgpk_process_simple_packet(struct psmouse *psmouse)294289{295290 struct input_dev *dev = psmouse->dev;296291 unsigned char *packet = psmouse->packet;297297- int x, y, left, right;292292+ int left = packet[0] & 1;293293+ int right = (packet[0] >> 1) & 1;294294+ int x = packet[1] - ((packet[0] << 4) & 0x100);295295+ int y = ((packet[0] << 3) & 0x100) - packet[2];298296299299- left = packet[0] & 1;300300- right = (packet[0] >> 1) & 1;297297+ if (packet[0] & 0xc0)298298+ hgpk_dbg(psmouse,299299+ "overflow -- 0x%02x 0x%02x 0x%02x\n",300300+ packet[0], packet[1], packet[2]);301301302302- x = packet[1] - ((packet[0] << 4) & 0x100);303303- y = ((packet[0] << 3) & 0x100) - packet[2];302302+ if (hgpk_discard_decay_hack(psmouse, x, y)) {303303+ if (tpdebug)304304+ hgpk_dbg(psmouse, "discarding\n");305305+ return;306306+ }304307305305- hgpk_jumpy_hack(psmouse, x, y);306308 hgpk_spewing_hack(psmouse, left, right, x, y);307309308310 if (tpdebug)···464180{465181 struct hgpk_data *priv = psmouse->private;466182467467- if (hgpk_validate_byte(psmouse->packet)) {468468- hgpk_dbg(psmouse, "%s: (%d) %02x %02x %02x\n",469469- __func__, psmouse->pktcnt, psmouse->packet[0],470470- psmouse->packet[1], psmouse->packet[2]);183183+ if (!hgpk_is_byte_valid(psmouse, psmouse->packet))471184 return PSMOUSE_BAD_DATA;472472- }473185474186 if (psmouse->pktcnt >= psmouse->pktsize) {475475- hgpk_process_packet(psmouse);187187+ if (priv->mode == HGPK_MODE_MOUSE)188188+ hgpk_process_simple_packet(psmouse);189189+ else190190+ hgpk_process_advanced_packet(psmouse);476191 return PSMOUSE_FULL_PACKET;477192 }478193···493210 return PSMOUSE_GOOD_DATA;494211}495212213213+static int hgpk_select_mode(struct psmouse *psmouse)214214+{215215+ struct ps2dev *ps2dev = &psmouse->ps2dev;216216+ struct hgpk_data *priv = psmouse->private;217217+ int i;218218+ int cmd;219219+220220+ /*221221+ * 4 disables to enable advanced mode222222+ * then 3 0xf2 bytes as the preamble for GS/PT selection223223+ */224224+ const int advanced_init[] = {225225+ PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,226226+ PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,227227+ 0xf2, 0xf2, 0xf2,228228+ };229229+230230+ switch (priv->mode) {231231+ case HGPK_MODE_MOUSE:232232+ psmouse->pktsize = 3;233233+ break;234234+235235+ case HGPK_MODE_GLIDESENSOR:236236+ case HGPK_MODE_PENTABLET:237237+ psmouse->pktsize = 6;238238+239239+ /* Switch to 'Advanced mode.', four disables in a row. */240240+ for (i = 0; i < ARRAY_SIZE(advanced_init); i++)241241+ if (ps2_command(ps2dev, NULL, advanced_init[i]))242242+ return -EIO;243243+244244+ /* select between GlideSensor (mouse) or PenTablet */245245+ cmd = priv->mode == HGPK_MODE_GLIDESENSOR ?246246+ PSMOUSE_CMD_SETSCALE11 : PSMOUSE_CMD_SETSCALE21;247247+248248+ if (ps2_command(ps2dev, NULL, cmd))249249+ return -EIO;250250+ break;251251+252252+ default:253253+ return -EINVAL;254254+ }255255+256256+ return 0;257257+}258258+259259+static void hgpk_setup_input_device(struct input_dev *input,260260+ struct input_dev *old_input,261261+ enum hgpk_mode mode)262262+{263263+ if (old_input) {264264+ input->name = old_input->name;265265+ input->phys = old_input->phys;266266+ input->id = old_input->id;267267+ input->dev.parent = old_input->dev.parent;268268+ }269269+270270+ memset(input->evbit, 0, sizeof(input->evbit));271271+ memset(input->relbit, 0, sizeof(input->relbit));272272+ memset(input->keybit, 0, sizeof(input->keybit));273273+274274+ /* All modes report left and right buttons */275275+ __set_bit(EV_KEY, input->evbit);276276+ __set_bit(BTN_LEFT, input->keybit);277277+ __set_bit(BTN_RIGHT, input->keybit);278278+279279+ switch (mode) {280280+ case HGPK_MODE_MOUSE:281281+ __set_bit(EV_REL, input->evbit);282282+ __set_bit(REL_X, input->relbit);283283+ __set_bit(REL_Y, input->relbit);284284+ break;285285+286286+ case HGPK_MODE_GLIDESENSOR:287287+ __set_bit(BTN_TOUCH, input->keybit);288288+ __set_bit(BTN_TOOL_FINGER, input->keybit);289289+290290+ __set_bit(EV_ABS, input->evbit);291291+292292+ /* GlideSensor has pressure sensor, PenTablet does not */293293+ input_set_abs_params(input, ABS_PRESSURE, 0, 15, 0, 0);294294+295295+ /* From device specs */296296+ input_set_abs_params(input, ABS_X, 0, 399, 0, 0);297297+ input_set_abs_params(input, ABS_Y, 0, 290, 0, 0);298298+299299+ /* Calculated by hand based on usable size (52mm x 38mm) */300300+ input_abs_set_res(input, ABS_X, 8);301301+ input_abs_set_res(input, ABS_Y, 8);302302+ break;303303+304304+ case HGPK_MODE_PENTABLET:305305+ __set_bit(BTN_TOUCH, input->keybit);306306+ __set_bit(BTN_TOOL_FINGER, input->keybit);307307+308308+ __set_bit(EV_ABS, input->evbit);309309+310310+ /* From device specs */311311+ input_set_abs_params(input, ABS_X, 0, 999, 0, 0);312312+ input_set_abs_params(input, ABS_Y, 5, 239, 0, 0);313313+314314+ /* Calculated by hand based on usable size (156mm x 38mm) */315315+ input_abs_set_res(input, ABS_X, 6);316316+ input_abs_set_res(input, ABS_Y, 8);317317+ break;318318+319319+ default:320320+ BUG();321321+ }322322+}323323+324324+static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate)325325+{326326+ int err;327327+328328+ psmouse_reset(psmouse);329329+330330+ if (recalibrate) {331331+ struct ps2dev *ps2dev = &psmouse->ps2dev;332332+333333+ /* send the recalibrate request */334334+ if (ps2_command(ps2dev, NULL, 0xf5) ||335335+ ps2_command(ps2dev, NULL, 0xf5) ||336336+ ps2_command(ps2dev, NULL, 0xe6) ||337337+ ps2_command(ps2dev, NULL, 0xf5)) {338338+ return -1;339339+ }340340+341341+ /* according to ALPS, 150mS is required for recalibration */342342+ msleep(150);343343+ }344344+345345+ err = hgpk_select_mode(psmouse);346346+ if (err) {347347+ hgpk_err(psmouse, "failed to select mode\n");348348+ return err;349349+ }350350+351351+ hgpk_reset_hack_state(psmouse);352352+353353+ return 0;354354+}355355+496356static int hgpk_force_recalibrate(struct psmouse *psmouse)497357{498358 struct ps2dev *ps2dev = &psmouse->ps2dev;499359 struct hgpk_data *priv = psmouse->private;360360+ int err;500361501362 /* C-series touchpads added the recalibrate command */502363 if (psmouse->model < HGPK_MODEL_C)503364 return 0;504365366366+ if (!autorecal) {367367+ hgpk_dbg(psmouse, "recalibrations disabled, ignoring\n");368368+ return 0;369369+ }370370+371371+ hgpk_dbg(psmouse, "recalibrating touchpad..\n");372372+505373 /* we don't want to race with the irq handler, nor with resyncs */506374 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);507375508376 /* start by resetting the device */509509- psmouse_reset(psmouse);377377+ err = hgpk_reset_device(psmouse, true);378378+ if (err)379379+ return err;510380511511- /* send the recalibrate request */512512- if (ps2_command(ps2dev, NULL, 0xf5) ||513513- ps2_command(ps2dev, NULL, 0xf5) ||514514- ps2_command(ps2dev, NULL, 0xe6) ||515515- ps2_command(ps2dev, NULL, 0xf5)) {516516- return -1;517517- }518518-519519- /* according to ALPS, 150mS is required for recalibration */520520- msleep(150);521521-522522- /* XXX: If a finger is down during this delay, recalibration will381381+ /*382382+ * XXX: If a finger is down during this delay, recalibration will523383 * detect capacitance incorrectly. This is a hardware bug, and524384 * we don't have a good way to deal with it. The 2s window stuff525385 * (below) is our best option for now.···673247674248 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);675249676676- /* After we recalibrate, we shouldn't get any packets for 2s. If677677- * we do, it's likely that someone's finger was on the touchpad.678678- * If someone's finger *was* on the touchpad, it's probably679679- * miscalibrated. So, we should schedule another recalibration250250+ if (tpdebug)251251+ hgpk_dbg(psmouse, "touchpad reactivated\n");252252+253253+ /*254254+ * If we get packets right away after recalibrating, it's likely255255+ * that a finger was on the touchpad. If so, it's probably256256+ * miscalibrated, so we optionally schedule another.680257 */681681- priv->recalib_window = jiffies + msecs_to_jiffies(recal_guard_time);258258+ if (recal_guard_time)259259+ priv->recalib_window = jiffies +260260+ msecs_to_jiffies(recal_guard_time);682261683262 return 0;684263}685264686265/*687687- * This kills power to the touchpad; according to ALPS, current consumption688688- * goes down to 50uA after running this. To turn power back on, we drive689689- * MS-DAT low.266266+ * This puts the touchpad in a power saving mode; according to ALPS, current267267+ * consumption goes down to 50uA after running this. To turn power back on,268268+ * we drive MS-DAT low. Measuring with a 1mA resolution ammeter says that269269+ * the current on the SUS_3.3V rail drops from 3mA or 4mA to 0 when we do this.270270+ *271271+ * We have no formal spec that details this operation -- the low-power272272+ * sequence came from a long-lost email trail.690273 */691691-static int hgpk_toggle_power(struct psmouse *psmouse, int enable)274274+static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable)692275{693276 struct ps2dev *ps2dev = &psmouse->ps2dev;694277 int timeo;278278+ int err;695279696280 /* Added on D-series touchpads */697281 if (psmouse->model < HGPK_MODEL_D)···715279 * the controller. Once we get an ACK back from it, it716280 * means we can continue with the touchpad re-init. ALPS717281 * tells us that 1s should be long enough, so set that as718718- * the upper bound.282282+ * the upper bound. (in practice, it takes about 3 loops.)719283 */720284 for (timeo = 20; timeo > 0; timeo--) {721285 if (!ps2_sendbyte(&psmouse->ps2dev,722286 PSMOUSE_CMD_DISABLE, 20))723287 break;724724- msleep(50);288288+ msleep(25);725289 }726290727727- psmouse_reset(psmouse);291291+ err = hgpk_reset_device(psmouse, false);292292+ if (err) {293293+ hgpk_err(psmouse, "Failed to reset device!\n");294294+ return err;295295+ }728296729297 /* should be all set, enable the touchpad */730298 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);731299 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);732732-300300+ hgpk_dbg(psmouse, "Touchpad powered up.\n");733301 } else {734302 hgpk_dbg(psmouse, "Powering off touchpad.\n");735735- psmouse_set_state(psmouse, PSMOUSE_IGNORE);736303737304 if (ps2_command(ps2dev, NULL, 0xec) ||738305 ps2_command(ps2dev, NULL, 0xec) ||739306 ps2_command(ps2dev, NULL, 0xea)) {740307 return -1;741308 }309309+310310+ psmouse_set_state(psmouse, PSMOUSE_IGNORE);742311743312 /* probably won't see an ACK, the touchpad will be off */744313 ps2_sendbyte(&psmouse->ps2dev, 0xec, 20);···760319761320static int hgpk_reconnect(struct psmouse *psmouse)762321{763763- /* During suspend/resume the ps2 rails remain powered. We don't want322322+ struct hgpk_data *priv = psmouse->private;323323+324324+ /*325325+ * During suspend/resume the ps2 rails remain powered. We don't want764326 * to do a reset because it's flush data out of buffers; however,765765- * earlier prototypes (B1) had some brokenness that required a reset. */327327+ * earlier prototypes (B1) had some brokenness that required a reset.328328+ */766329 if (olpc_board_at_least(olpc_board(0xb2)))767330 if (psmouse->ps2dev.serio->dev.power.power_state.event !=768331 PM_EVENT_ON)769332 return 0;770333771771- psmouse_reset(psmouse);772772-773773- return 0;334334+ priv->powered = 1;335335+ return hgpk_reset_device(psmouse, false);774336}775337776338static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf)···799355 * hgpk_toggle_power will deal w/ state so800356 * we're not racing w/ irq801357 */802802- err = hgpk_toggle_power(psmouse, value);358358+ err = hgpk_toggle_powersave(psmouse, value);803359 if (!err)804360 priv->powered = value;805361 }···809365810366__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,811367 hgpk_show_powered, hgpk_set_powered, false);368368+369369+static ssize_t attr_show_mode(struct psmouse *psmouse, void *data, char *buf)370370+{371371+ struct hgpk_data *priv = psmouse->private;372372+373373+ return sprintf(buf, "%s\n", hgpk_mode_names[priv->mode]);374374+}375375+376376+static ssize_t attr_set_mode(struct psmouse *psmouse, void *data,377377+ const char *buf, size_t len)378378+{379379+ struct hgpk_data *priv = psmouse->private;380380+ enum hgpk_mode old_mode = priv->mode;381381+ enum hgpk_mode new_mode = hgpk_mode_from_name(buf, len);382382+ struct input_dev *old_dev = psmouse->dev;383383+ struct input_dev *new_dev;384384+ int err;385385+386386+ if (new_mode == HGPK_MODE_INVALID)387387+ return -EINVAL;388388+389389+ if (old_mode == new_mode)390390+ return len;391391+392392+ new_dev = input_allocate_device();393393+ if (!new_dev)394394+ return -ENOMEM;395395+396396+ psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);397397+398398+ /* Switch device into the new mode */399399+ priv->mode = new_mode;400400+ err = hgpk_reset_device(psmouse, false);401401+ if (err)402402+ goto err_try_restore;403403+404404+ hgpk_setup_input_device(new_dev, old_dev, new_mode);405405+406406+ psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);407407+408408+ err = input_register_device(new_dev);409409+ if (err)410410+ goto err_try_restore;411411+412412+ psmouse->dev = new_dev;413413+ input_unregister_device(old_dev);414414+415415+ return len;416416+417417+err_try_restore:418418+ input_free_device(new_dev);419419+ priv->mode = old_mode;420420+ hgpk_reset_device(psmouse, false);421421+422422+ return err;423423+}424424+425425+PSMOUSE_DEFINE_ATTR(hgpk_mode, S_IWUSR | S_IRUGO, NULL,426426+ attr_show_mode, attr_set_mode);812427813428static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,814429 void *data, char *buf)···904401905402 device_remove_file(&psmouse->ps2dev.serio->dev,906403 &psmouse_attr_powered.dattr);404404+ device_remove_file(&psmouse->ps2dev.serio->dev,405405+ &psmouse_attr_hgpk_mode.dattr);907406908407 if (psmouse->model >= HGPK_MODEL_C)909408 device_remove_file(&psmouse->ps2dev.serio->dev,···921416 struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);922417 struct psmouse *psmouse = priv->psmouse;923418924924- hgpk_dbg(psmouse, "recalibrating touchpad..\n");925925-926419 if (hgpk_force_recalibrate(psmouse))927420 hgpk_err(psmouse, "recalibration failed!\n");928421}929422930423static int hgpk_register(struct psmouse *psmouse)931424{425425+ struct hgpk_data *priv = psmouse->private;932426 int err;933427934428 /* register handlers */···935431 psmouse->poll = hgpk_poll;936432 psmouse->disconnect = hgpk_disconnect;937433 psmouse->reconnect = hgpk_reconnect;938938- psmouse->pktsize = 3;939434940435 /* Disable the idle resync. */941436 psmouse->resync_time = 0;942437 /* Reset after a lot of bad bytes. */943438 psmouse->resetafter = 1024;944439440440+ hgpk_setup_input_device(psmouse->dev, NULL, priv->mode);441441+945442 err = device_create_file(&psmouse->ps2dev.serio->dev,946443 &psmouse_attr_powered.dattr);947444 if (err) {948445 hgpk_err(psmouse, "Failed creating 'powered' sysfs node\n");949446 return err;447447+ }448448+449449+ err = device_create_file(&psmouse->ps2dev.serio->dev,450450+ &psmouse_attr_hgpk_mode.dattr);451451+ if (err) {452452+ hgpk_err(psmouse, "Failed creating 'hgpk_mode' sysfs node\n");453453+ goto err_remove_powered;950454 }951455952456 /* C-series touchpads added the recalibrate command */···964452 if (err) {965453 hgpk_err(psmouse,966454 "Failed creating 'recalibrate' sysfs node\n");967967- device_remove_file(&psmouse->ps2dev.serio->dev,968968- &psmouse_attr_powered.dattr);969969- return err;455455+ goto err_remove_mode;970456 }971457 }972458973459 return 0;460460+461461+err_remove_mode:462462+ device_remove_file(&psmouse->ps2dev.serio->dev,463463+ &psmouse_attr_hgpk_mode.dattr);464464+err_remove_powered:465465+ device_remove_file(&psmouse->ps2dev.serio->dev,466466+ &psmouse_attr_powered.dattr);467467+ return err;974468}975469976470int hgpk_init(struct psmouse *psmouse)977471{978472 struct hgpk_data *priv;979979- int err = -ENOMEM;473473+ int err;980474981475 priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL);982982- if (!priv)476476+ if (!priv) {477477+ err = -ENOMEM;983478 goto alloc_fail;479479+ }984480985481 psmouse->private = priv;482482+986483 priv->psmouse = psmouse;987484 priv->powered = true;485485+ priv->mode = hgpk_default_mode;988486 INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);989487990990- err = psmouse_reset(psmouse);488488+ err = hgpk_reset_device(psmouse, false);991489 if (err)992490 goto init_fail;993491···1052530 }10535311054532 return 0;533533+}534534+535535+void hgpk_module_init(void)536536+{537537+ hgpk_default_mode = hgpk_mode_from_name(hgpk_mode_name,538538+ strlen(hgpk_mode_name));539539+ if (hgpk_default_mode == HGPK_MODE_INVALID) {540540+ hgpk_default_mode = HGPK_MODE_MOUSE;541541+ strlcpy(hgpk_mode_name, hgpk_mode_names[HGPK_MODE_MOUSE],542542+ sizeof(hgpk_mode_name));543543+ }1055544}
+30-1
drivers/input/mouse/hgpk.h
···55#ifndef _HGPK_H66#define _HGPK_H7788+#define HGPK_GS 0xff /* The GlideSensor */99+#define HGPK_PT 0xcf /* The PenTablet */1010+811enum hgpk_model_t {912 HGPK_MODEL_PREA = 0x0a, /* pre-B1s */1013 HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */···1613 HGPK_MODEL_D = 0x50, /* C1, mass production */1714};18151616+enum hgpk_spew_flag {1717+ NO_SPEW,1818+ MAYBE_SPEWING,1919+ SPEW_DETECTED,2020+ RECALIBRATING,2121+};2222+2323+#define SPEW_WATCH_COUNT 42 /* at 12ms/packet, this is 1/2 second */2424+2525+enum hgpk_mode {2626+ HGPK_MODE_MOUSE,2727+ HGPK_MODE_GLIDESENSOR,2828+ HGPK_MODE_PENTABLET,2929+ HGPK_MODE_INVALID3030+};3131+1932struct hgpk_data {2033 struct psmouse *psmouse;3434+ enum hgpk_mode mode;2135 bool powered;2222- int count, x_tally, y_tally; /* hardware workaround stuff */3636+ enum hgpk_spew_flag spew_flag;3737+ int spew_count, x_tally, y_tally; /* spew detection */2338 unsigned long recalib_window;2439 struct delayed_work recalib_wq;4040+ int abs_x, abs_y;4141+ int dupe_count;4242+ int xbigj, ybigj, xlast, ylast; /* jumpiness detection */4343+ int xsaw_secondary, ysaw_secondary; /* jumpiness detection */2544};26452746#define hgpk_dbg(psmouse, format, arg...) \···5833 dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)59346035#ifdef CONFIG_MOUSE_PS2_OLPC3636+void hgpk_module_init(void);6137int hgpk_detect(struct psmouse *psmouse, bool set_properties);6238int hgpk_init(struct psmouse *psmouse);6339#else4040+static inline void hgpk_module_init(void)4141+{4242+}6443static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties)6544{6645 return -ENODEV;
+1
drivers/input/mouse/psmouse-base.c
···1711171117121712 lifebook_module_init();17131713 synaptics_module_init();17141714+ hgpk_module_init();1714171517151716 kpsmoused_wq = create_singlethread_workqueue("kpsmoused");17161717 if (!kpsmoused_wq) {
+122-7
drivers/input/mouse/synaptics.c
···25252626#include <linux/module.h>2727#include <linux/dmi.h>2828-#include <linux/input.h>2828+#include <linux/input/mt.h>2929#include <linux/serio.h>3030#include <linux/libps2.h>3131#include <linux/slab.h>···279279 synaptics_mode_cmd(psmouse, priv->mode);280280}281281282282+static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)283283+{284284+ static unsigned char param = 0xc8;285285+ struct synaptics_data *priv = psmouse->private;286286+287287+ if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))288288+ return 0;289289+290290+ if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))291291+ return -1;292292+ if (ps2_command(&psmouse->ps2dev, ¶m, PSMOUSE_CMD_SETRATE))293293+ return -1;294294+295295+ /* Advanced gesture mode also sends multi finger data */296296+ priv->capabilities |= BIT(1);297297+298298+ return 0;299299+}300300+282301/*****************************************************************************283302 * Synaptics pass-through PS/2 port support284303 ****************************************************************************/···399380 * Functions to interpret the absolute mode packets400381 ****************************************************************************/401382402402-static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw)383383+static int synaptics_parse_hw_state(const unsigned char buf[],384384+ struct synaptics_data *priv,385385+ struct synaptics_hw_state *hw)403386{404387 memset(hw, 0, sizeof(struct synaptics_hw_state));405388···417396 hw->w = (((buf[0] & 0x30) >> 2) |418397 ((buf[0] & 0x04) >> 1) |419398 ((buf[3] & 0x04) >> 2));399399+400400+ if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) {401401+ /* Gesture packet: (x, y, z) at half resolution */402402+ priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1;403403+ priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1;404404+ priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1;405405+ return 1;406406+ }420407421408 hw->left = (buf[0] & 0x01) ? 1 : 0;422409 hw->right = (buf[0] & 0x02) ? 1 : 0;···481452 hw->left = (buf[0] & 0x01) ? 1 : 0;482453 hw->right = (buf[0] & 0x02) ? 1 : 0;483454 }455455+456456+ return 0;457457+}458458+459459+static void set_slot(struct input_dev *dev, int slot, bool active, int x, int y)460460+{461461+ input_mt_slot(dev, slot);462462+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);463463+ if (active) {464464+ input_report_abs(dev, ABS_MT_POSITION_X, x);465465+ input_report_abs(dev, ABS_MT_POSITION_Y,466466+ YMAX_NOMINAL + YMIN_NOMINAL - y);467467+ }468468+}469469+470470+static void synaptics_report_semi_mt_data(struct input_dev *dev,471471+ const struct synaptics_hw_state *a,472472+ const struct synaptics_hw_state *b,473473+ int num_fingers)474474+{475475+ if (num_fingers >= 2) {476476+ set_slot(dev, 0, true, min(a->x, b->x), min(a->y, b->y));477477+ set_slot(dev, 1, true, max(a->x, b->x), max(a->y, b->y));478478+ } else if (num_fingers == 1) {479479+ set_slot(dev, 0, true, a->x, a->y);480480+ set_slot(dev, 1, false, 0, 0);481481+ } else {482482+ set_slot(dev, 0, false, 0, 0);483483+ set_slot(dev, 1, false, 0, 0);484484+ }484485}485486486487/*···525466 int finger_width;526467 int i;527468528528- synaptics_parse_hw_state(psmouse->packet, priv, &hw);469469+ if (synaptics_parse_hw_state(psmouse->packet, priv, &hw))470470+ return;529471530472 if (hw.scroll) {531473 priv->scroll += hw.scroll;···548488 return;549489 }550490551551- if (hw.z > 0) {491491+ if (hw.z > 0 && hw.x > 1) {552492 num_fingers = 1;553493 finger_width = 5;554494 if (SYN_CAP_EXTENDED(priv->capabilities)) {···572512 finger_width = 0;573513 }574514515515+ if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))516516+ synaptics_report_semi_mt_data(dev, &hw, &priv->mt, num_fingers);517517+575518 /* Post events576519 * BTN_TOUCH has to be first as mousedev relies on it when doing577520 * absolute -> relative conversion···582519 if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1);583520 if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0);584521585585- if (hw.z > 0) {522522+ if (num_fingers > 0) {586523 input_report_abs(dev, ABS_X, hw.x);587524 input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y);588525 }···685622{686623 int i;687624625625+ __set_bit(INPUT_PROP_POINTER, dev->propbit);626626+688627 __set_bit(EV_ABS, dev->evbit);689628 input_set_abs_params(dev, ABS_X,690629 XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0);691630 input_set_abs_params(dev, ABS_Y,692631 YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0);693632 input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);633633+634634+ if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) {635635+ __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);636636+ input_mt_init_slots(dev, 2);637637+ input_set_abs_params(dev, ABS_MT_POSITION_X, XMIN_NOMINAL,638638+ priv->x_max ?: XMAX_NOMINAL, 0, 0);639639+ input_set_abs_params(dev, ABS_MT_POSITION_Y, YMIN_NOMINAL,640640+ priv->y_max ?: YMAX_NOMINAL, 0, 0);641641+ }694642695643 if (SYN_CAP_PALMDETECT(priv->capabilities))696644 input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);···737663 input_abs_set_res(dev, ABS_Y, priv->y_res);738664739665 if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {666666+ __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);740667 /* Clickpads report only left button */741668 __clear_bit(BTN_RIGHT, dev->keybit);742669 __clear_bit(BTN_MIDDLE, dev->keybit);···774699775700 if (synaptics_set_absolute_mode(psmouse)) {776701 printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");702702+ return -1;703703+ }704704+705705+ if (synaptics_set_advanced_gesture_mode(psmouse)) {706706+ printk(KERN_ERR "Advanced gesture mode reconnect failed.\n");777707 return -1;778708 }779709···824744#endif825745};826746747747+static bool broken_olpc_ec;748748+749749+static const struct dmi_system_id __initconst olpc_dmi_table[] = {750750+#if defined(CONFIG_DMI) && defined(CONFIG_OLPC)751751+ {752752+ /* OLPC XO-1 or XO-1.5 */753753+ .matches = {754754+ DMI_MATCH(DMI_SYS_VENDOR, "OLPC"),755755+ DMI_MATCH(DMI_PRODUCT_NAME, "XO"),756756+ },757757+ },758758+ { }759759+#endif760760+};761761+827762void __init synaptics_module_init(void)828763{829764 impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);765765+ broken_olpc_ec = dmi_check_system(olpc_dmi_table);830766}831767832768int synaptics_init(struct psmouse *psmouse)833769{834770 struct synaptics_data *priv;771771+772772+ /*773773+ * The OLPC XO has issues with Synaptics' absolute mode; similarly to774774+ * the HGPK, it quickly degrades and the hardware becomes jumpy and775775+ * overly sensitive. Not only that, but the constant packet spew776776+ * (even at a lowered 40pps rate) overloads the EC such that key777777+ * presses on the keyboard are missed. Given all of that, don't778778+ * even attempt to use Synaptics mode. Relative mode seems to work779779+ * just fine.780780+ */781781+ if (broken_olpc_ec) {782782+ printk(KERN_INFO "synaptics: OLPC XO detected, not enabling Synaptics protocol.\n");783783+ return -ENODEV;784784+ }835785836786 psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL);837787 if (!priv)···876766877767 if (synaptics_set_absolute_mode(psmouse)) {878768 printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");769769+ goto init_fail;770770+ }771771+772772+ if (synaptics_set_advanced_gesture_mode(psmouse)) {773773+ printk(KERN_ERR "Advanced gesture mode init failed.\n");879774 goto init_fail;880775 }881776···917802918803 /*919804 * Toshiba's KBC seems to have trouble handling data from920920- * Synaptics as full rate, switch to lower rate which is roughly921921- * thye same as rate of standard PS/2 mouse.805805+ * Synaptics at full rate. Switch to a lower rate (roughly806806+ * the same rate as a standard PS/2 mouse).922807 */923808 if (psmouse->rate >= 80 && impaired_toshiba_kbc) {924809 printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n",
···305305static int __init hp_sdc_mlc_init(void)306306{307307 hil_mlc *mlc = &hp_sdc_mlc;308308+ int err;308309309310#ifdef __mc68000__310311 if (!MACH_IS_HP300)···324323 mlc->out = &hp_sdc_mlc_out;325324 mlc->priv = &hp_sdc_mlc_priv;326325327327- if (hil_mlc_register(mlc)) {326326+ err = hil_mlc_register(mlc);327327+ if (err) {328328 printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n");329329- goto err0;329329+ return err;330330 }331331332332 if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) {333333 printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n");334334- goto err1;334334+ if (hil_mlc_unregister(mlc))335335+ printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n"336336+ "This is bad. Could cause an oops.\n");337337+ return -EBUSY;335338 }339339+336340 return 0;337337- err1:338338- if (hil_mlc_unregister(mlc))339339- printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n"340340- "This is bad. Could cause an oops.\n");341341- err0:342342- return -EBUSY;343341}344342345343static void __exit hp_sdc_mlc_exit(void)
+18-19
drivers/input/serio/i8042-x86ia64io.h
···553553 */554554static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {555555 {556556+ /* Acer Aspire 5100 */557557+ .matches = {558558+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),559559+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),560560+ },561561+ },562562+ {556563 /* Acer Aspire 5610 */557564 .matches = {558565 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),···759752#endif760753761754 if (i8042_nopnp) {762762- printk(KERN_INFO "i8042: PNP detection disabled\n");755755+ pr_info("PNP detection disabled\n");763756 return 0;764757 }765758···776769#if defined(__ia64__)777770 return -ENODEV;778771#else779779- printk(KERN_INFO "PNP: No PS/2 controller found. Probing ports directly.\n");772772+ pr_info("PNP: No PS/2 controller found. Probing ports directly.\n");780773 return 0;781774#endif782775 }···788781 snprintf(aux_irq_str, sizeof(aux_irq_str),789782 "%d", i8042_pnp_aux_irq);790783791791- printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n",784784+ pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n",792785 i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",793786 i8042_pnp_aux_name,794787 i8042_pnp_data_reg, i8042_pnp_command_reg,···805798 if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) &&806799 i8042_pnp_data_reg != i8042_data_reg) ||807800 !i8042_pnp_data_reg) {808808- printk(KERN_WARNING809809- "PNP: PS/2 controller has invalid data port %#x; "810810- "using default %#x\n",801801+ pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n",811802 i8042_pnp_data_reg, i8042_data_reg);812803 i8042_pnp_data_reg = i8042_data_reg;813804 pnp_data_busted = true;···814809 if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) &&815810 i8042_pnp_command_reg != i8042_command_reg) ||816811 !i8042_pnp_command_reg) {817817- printk(KERN_WARNING818818- "PNP: PS/2 controller has invalid command port %#x; "819819- "using default %#x\n",812812+ pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n",820813 i8042_pnp_command_reg, i8042_command_reg);821814 i8042_pnp_command_reg = i8042_command_reg;822815 pnp_data_busted = true;823816 }824817825818 if (!i8042_nokbd && !i8042_pnp_kbd_irq) {826826- printk(KERN_WARNING827827- "PNP: PS/2 controller doesn't have KBD irq; "828828- "using default %d\n", i8042_kbd_irq);819819+ pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n",820820+ i8042_kbd_irq);829821 i8042_pnp_kbd_irq = i8042_kbd_irq;830822 pnp_data_busted = true;831823 }832824833825 if (!i8042_noaux && !i8042_pnp_aux_irq) {834826 if (!pnp_data_busted && i8042_pnp_kbd_irq) {835835- printk(KERN_WARNING836836- "PNP: PS/2 appears to have AUX port disabled, "837837- "if this is incorrect please boot with "838838- "i8042.nopnp\n");827827+ pr_warn("PNP: PS/2 appears to have AUX port disabled, "828828+ "if this is incorrect please boot with i8042.nopnp\n");839829 i8042_noaux = true;840830 } else {841841- printk(KERN_WARNING842842- "PNP: PS/2 controller doesn't have AUX irq; "843843- "using default %d\n", i8042_aux_irq);831831+ pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n",832832+ i8042_aux_irq);844833 i8042_pnp_aux_irq = i8042_aux_irq;845834 }846835 }
+43-49
drivers/input/serio/i8042.c
···1010 * the Free Software Foundation.1111 */12121313+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt1414+1315#include <linux/types.h>1416#include <linux/delay.h>1517#include <linux/module.h>···227225 udelay(50);228226 data = i8042_read_data();229227 i++;230230- dbg("%02x <- i8042 (flush, %s)", data,231231- str & I8042_STR_AUXDATA ? "aux" : "kbd");228228+ dbg("%02x <- i8042 (flush, %s)\n",229229+ data, str & I8042_STR_AUXDATA ? "aux" : "kbd");232230 }233231234232 spin_unlock_irqrestore(&i8042_lock, flags);···255253 if (error)256254 return error;257255258258- dbg("%02x -> i8042 (command)", command & 0xff);256256+ dbg("%02x -> i8042 (command)\n", command & 0xff);259257 i8042_write_command(command & 0xff);260258261259 for (i = 0; i < ((command >> 12) & 0xf); i++) {262260 error = i8042_wait_write();263261 if (error)264262 return error;265265- dbg("%02x -> i8042 (parameter)", param[i]);263263+ dbg("%02x -> i8042 (parameter)\n", param[i]);266264 i8042_write_data(param[i]);267265 }268266269267 for (i = 0; i < ((command >> 8) & 0xf); i++) {270268 error = i8042_wait_read();271269 if (error) {272272- dbg(" -- i8042 (timeout)");270270+ dbg(" -- i8042 (timeout)\n");273271 return error;274272 }275273276274 if (command == I8042_CMD_AUX_LOOP &&277275 !(i8042_read_status() & I8042_STR_AUXDATA)) {278278- dbg(" -- i8042 (auxerr)");276276+ dbg(" -- i8042 (auxerr)\n");279277 return -1;280278 }281279282280 param[i] = i8042_read_data();283283- dbg("%02x <- i8042 (return)", param[i]);281281+ dbg("%02x <- i8042 (return)\n", param[i]);284282 }285283286284 return 0;···311309 spin_lock_irqsave(&i8042_lock, flags);312310313311 if (!(retval = i8042_wait_write())) {314314- dbg("%02x -> i8042 (kbd-data)", c);312312+ dbg("%02x -> i8042 (kbd-data)\n", c);315313 i8042_write_data(c);316314 }317315···357355358356 i8042_ctr &= ~irq_bit;359357 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))360360- printk(KERN_WARNING361361- "i8042.c: Can't write CTR while closing %s port.\n",362362- port_name);358358+ pr_warn("Can't write CTR while closing %s port\n", port_name);363359364360 udelay(50);365361366362 i8042_ctr &= ~disable_bit;367363 i8042_ctr |= irq_bit;368364 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))369369- printk(KERN_ERR "i8042.c: Can't reactivate %s port.\n",370370- port_name);365365+ pr_err("Can't reactivate %s port\n", port_name);371366372367 /*373368 * See if there is any data appeared while we were messing with···455456 str = i8042_read_status();456457 if (unlikely(~str & I8042_STR_OBF)) {457458 spin_unlock_irqrestore(&i8042_lock, flags);458458- if (irq) dbg("Interrupt %d, without any data", irq);459459+ if (irq)460460+ dbg("Interrupt %d, without any data\n", irq);459461 ret = 0;460462 goto out;461463 }···469469470470 dfl = 0;471471 if (str & I8042_STR_MUXERR) {472472- dbg("MUX error, status is %02x, data is %02x", str, data);472472+ dbg("MUX error, status is %02x, data is %02x\n",473473+ str, data);473474/*474475 * When MUXERR condition is signalled the data register can only contain475476 * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately···513512 port = &i8042_ports[port_no];514513 serio = port->exists ? port->serio : NULL;515514516516- dbg("%02x <- i8042 (interrupt, %d, %d%s%s)",515515+ dbg("%02x <- i8042 (interrupt, %d, %d%s%s)\n",517516 data, port_no, irq,518517 dfl & SERIO_PARITY ? ", bad parity" : "",519518 dfl & SERIO_TIMEOUT ? ", timeout" : "");···541540 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {542541 i8042_ctr &= ~I8042_CTR_KBDINT;543542 i8042_ctr |= I8042_CTR_KBDDIS;544544- printk(KERN_ERR "i8042.c: Failed to enable KBD port.\n");543543+ pr_err("Failed to enable KBD port\n");545544 return -EIO;546545 }547546···560559 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {561560 i8042_ctr &= ~I8042_CTR_AUXINT;562561 i8042_ctr |= I8042_CTR_AUXDIS;563563- printk(KERN_ERR "i8042.c: Failed to enable AUX port.\n");562562+ pr_err("Failed to enable AUX port\n");564563 return -EIO;565564 }566565···642641 if (i8042_set_mux_mode(true, &mux_version))643642 return -1;644643645645- printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",644644+ pr_info("Detected active multiplexing controller, rev %d.%d\n",646645 (mux_version >> 4) & 0xf, mux_version & 0xf);647646648647/*···652651 i8042_ctr &= ~I8042_CTR_AUXINT;653652654653 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {655655- printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n");654654+ pr_err("Failed to disable AUX port, can't use MUX\n");656655 return -EIO;657656 }658657···677676 str = i8042_read_status();678677 if (str & I8042_STR_OBF) {679678 data = i8042_read_data();680680- dbg("%02x <- i8042 (aux_test_irq, %s)",681681- data, str & I8042_STR_AUXDATA ? "aux" : "kbd");679679+ dbg("%02x <- i8042 (aux_test_irq, %s)\n",680680+ data, str & I8042_STR_AUXDATA ? "aux" : "kbd");682681 if (i8042_irq_being_tested &&683682 data == 0xa5 && (str & I8042_STR_AUXDATA))684683 complete(&i8042_aux_irq_delivered);···771770 */772771773772 if (i8042_toggle_aux(false)) {774774- printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n");775775- printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n");773773+ pr_warn("Failed to disable AUX port, but continuing anyway... Is this a SiS?\n");774774+ pr_warn("If AUX port is really absent please use the 'i8042.noaux' option\n");776775 }777776778777 if (i8042_toggle_aux(true))···820819 * AUX IRQ was never delivered so we need to flush the controller to821820 * get rid of the byte we put there; otherwise keyboard may not work.822821 */823823- dbg(" -- i8042 (aux irq test timeout)");822822+ dbg(" -- i8042 (aux irq test timeout)\n");824823 i8042_flush();825824 retval = -1;826825 }···846845static int i8042_controller_check(void)847846{848847 if (i8042_flush() == I8042_BUFFER_SIZE) {849849- printk(KERN_ERR "i8042.c: No controller found.\n");848848+ pr_err("No controller found\n");850849 return -ENODEV;851850 }852851···865864 do {866865867866 if (i8042_command(¶m, I8042_CMD_CTL_TEST)) {868868- printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");867867+ pr_err("i8042 controller self test timeout\n");869868 return -ENODEV;870869 }871870872871 if (param == I8042_RET_CTL_TEST)873872 return 0;874873875875- printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",876876- param, I8042_RET_CTL_TEST);874874+ pr_err("i8042 controller selftest failed. (%#x != %#x)\n",875875+ param, I8042_RET_CTL_TEST);877876 msleep(50);878877 } while (i++ < 5);879878···884883 * and user will still get a working keyboard. This is especially885884 * important on netbooks. On other arches we trust hardware more.886885 */887887- printk(KERN_INFO888888- "i8042: giving up on controller selftest, continuing anyway...\n");886886+ pr_info("giving up on controller selftest, continuing anyway...\n");889887 return 0;890888#else891889 return -EIO;···909909910910 do {911911 if (n >= 10) {912912- printk(KERN_ERR913913- "i8042.c: Unable to get stable CTR read.\n");912912+ pr_err("Unable to get stable CTR read\n");914913 return -EIO;915914 }916915···917918 udelay(50);918919919920 if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) {920920- printk(KERN_ERR921921- "i8042.c: Can't read CTR while initializing i8042.\n");921921+ pr_err("Can't read CTR while initializing i8042\n");922922 return -EIO;923923 }924924···941943 if (i8042_unlock)942944 i8042_ctr |= I8042_CTR_IGNKEYLOCK;943945 else944944- printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");946946+ pr_warn("Warning: Keylock active\n");945947 }946948 spin_unlock_irqrestore(&i8042_lock, flags);947949···968970 */969971970972 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {971971- printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n");973973+ pr_err("Can't write CTR while initializing i8042\n");972974 return -EIO;973975 }974976···9981000 i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT);999100110001002 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))10011001- printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n");10031003+ pr_warn("Can't write CTR while resetting\n");1002100410031005/*10041006 * Disable MUX mode if present.···10191021 */1020102210211023 if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR))10221022- printk(KERN_WARNING "i8042.c: Can't restore CTR.\n");10241024+ pr_warn("Can't restore CTR\n");10231025}1024102610251027···10431045 led = (state) ? 0x01 | 0x04 : 0;10441046 while (i8042_read_status() & I8042_STR_IBF)10451047 DELAY;10461046- dbg("%02x -> i8042 (panic blink)", 0xed);10481048+ dbg("%02x -> i8042 (panic blink)\n", 0xed);10471049 i8042_suppress_kbd_ack = 2;10481050 i8042_write_data(0xed); /* set leds */10491051 DELAY;10501052 while (i8042_read_status() & I8042_STR_IBF)10511053 DELAY;10521054 DELAY;10531053- dbg("%02x -> i8042 (panic blink)", led);10551055+ dbg("%02x -> i8042 (panic blink)\n", led);10541056 i8042_write_data(led);10551057 DELAY;10561058 return delay;···1066106810671069 error = i8042_command(¶m, 0x1059);10681070 if (error)10691069- printk(KERN_WARNING10701070- "Failed to enable DRITEK extension: %d\n",10711071- error);10711071+ pr_warn("Failed to enable DRITEK extension: %d\n", error);10721072}10731073#endif10741074···11011105 i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS;11021106 i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT);11031107 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {11041104- printk(KERN_WARNING "i8042: Can't write CTR to resume, retrying...\n");11081108+ pr_warn("Can't write CTR to resume, retrying...\n");11051109 msleep(50);11061110 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {11071107- printk(KERN_ERR "i8042: CTR write retry failed\n");11111111+ pr_err("CTR write retry failed\n");11081112 return -EIO;11091113 }11101114 }···1117112111181122 if (i8042_mux_present) {11191123 if (i8042_set_mux_mode(true, NULL) || i8042_enable_mux_ports())11201120- printk(KERN_WARNING11211121- "i8042: failed to resume active multiplexor, "11221122- "mouse won't work.\n");11241124+ pr_warn("failed to resume active multiplexor, mouse won't work\n");11231125 } else if (i8042_ports[I8042_AUX_PORT_NO].serio)11241126 i8042_enable_aux_port();11251127
+9-5
drivers/input/serio/i8042.h
···8989#ifdef DEBUG9090static unsigned long i8042_start_time;9191#define dbg_init() do { i8042_start_time = jiffies; } while (0)9292-#define dbg(format, arg...) \9393- do { \9292+#define dbg(format, arg...) \9393+ do { \9494 if (i8042_debug) \9595- printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" , \9696- ## arg, (int) (jiffies - i8042_start_time)); \9595+ printk(KERN_DEBUG KBUILD_MODNAME ": [%d] " format, \9696+ (int) (jiffies - i8042_start_time), ##arg); \9797 } while (0)9898#else9999#define dbg_init() do { } while (0)100100-#define dbg(format, arg...) do {} while (0)100100+#define dbg(format, arg...) \101101+ do { \102102+ if (0) \103103+ printk(KERN_DEBUG pr_fmt(format), ##arg); \104104+ } while (0)101105#endif102106103107#endif /* _I8042_H */
···3232#include <linux/module.h>3333#include <linux/serio.h>3434#include <linux/errno.h>3535-#include <linux/wait.h>3635#include <linux/sched.h>3736#include <linux/slab.h>3838-#include <linux/kthread.h>3737+#include <linux/workqueue.h>3938#include <linux/mutex.h>40394140MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");···43444445/*4546 * serio_mutex protects entire serio subsystem and is taken every time4646- * serio port or driver registrered or unregistered.4747+ * serio port or driver registered or unregistered.4748 */4849static DEFINE_MUTEX(serio_mutex);4950···164165165166static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */166167static LIST_HEAD(serio_event_list);167167-static DECLARE_WAIT_QUEUE_HEAD(serio_wait);168168-static struct task_struct *serio_task;168168+169169+static struct serio_event *serio_get_event(void)170170+{171171+ struct serio_event *event = NULL;172172+ unsigned long flags;173173+174174+ spin_lock_irqsave(&serio_event_lock, flags);175175+176176+ if (!list_empty(&serio_event_list)) {177177+ event = list_first_entry(&serio_event_list,178178+ struct serio_event, node);179179+ list_del_init(&event->node);180180+ }181181+182182+ spin_unlock_irqrestore(&serio_event_lock, flags);183183+ return event;184184+}185185+186186+static void serio_free_event(struct serio_event *event)187187+{188188+ module_put(event->owner);189189+ kfree(event);190190+}191191+192192+static void serio_remove_duplicate_events(struct serio_event *event)193193+{194194+ struct serio_event *e, *next;195195+ unsigned long flags;196196+197197+ spin_lock_irqsave(&serio_event_lock, flags);198198+199199+ list_for_each_entry_safe(e, next, &serio_event_list, node) {200200+ if (event->object == e->object) {201201+ /*202202+ * If this event is of different type we should not203203+ * look further - we only suppress duplicate events204204+ * that were sent back-to-back.205205+ */206206+ if (event->type != e->type)207207+ break;208208+209209+ list_del_init(&e->node);210210+ serio_free_event(e);211211+ }212212+ }213213+214214+ spin_unlock_irqrestore(&serio_event_lock, flags);215215+}216216+217217+static void serio_handle_event(struct work_struct *work)218218+{219219+ struct serio_event *event;220220+221221+ mutex_lock(&serio_mutex);222222+223223+ while ((event = serio_get_event())) {224224+225225+ switch (event->type) {226226+227227+ case SERIO_REGISTER_PORT:228228+ serio_add_port(event->object);229229+ break;230230+231231+ case SERIO_RECONNECT_PORT:232232+ serio_reconnect_port(event->object);233233+ break;234234+235235+ case SERIO_RESCAN_PORT:236236+ serio_disconnect_port(event->object);237237+ serio_find_driver(event->object);238238+ break;239239+240240+ case SERIO_RECONNECT_SUBTREE:241241+ serio_reconnect_subtree(event->object);242242+ break;243243+244244+ case SERIO_ATTACH_DRIVER:245245+ serio_attach_driver(event->object);246246+ break;247247+ }248248+249249+ serio_remove_duplicate_events(event);250250+ serio_free_event(event);251251+ }252252+253253+ mutex_unlock(&serio_mutex);254254+}255255+256256+static DECLARE_WORK(serio_event_work, serio_handle_event);169257170258static int serio_queue_event(void *object, struct module *owner,171259 enum serio_event_type event_type)···298212 event->owner = owner;299213300214 list_add_tail(&event->node, &serio_event_list);301301- wake_up(&serio_wait);215215+ schedule_work(&serio_event_work);302216303217out:304218 spin_unlock_irqrestore(&serio_event_lock, flags);305219 return retval;306306-}307307-308308-static void serio_free_event(struct serio_event *event)309309-{310310- module_put(event->owner);311311- kfree(event);312312-}313313-314314-static void serio_remove_duplicate_events(struct serio_event *event)315315-{316316- struct serio_event *e, *next;317317- unsigned long flags;318318-319319- spin_lock_irqsave(&serio_event_lock, flags);320320-321321- list_for_each_entry_safe(e, next, &serio_event_list, node) {322322- if (event->object == e->object) {323323- /*324324- * If this event is of different type we should not325325- * look further - we only suppress duplicate events326326- * that were sent back-to-back.327327- */328328- if (event->type != e->type)329329- break;330330-331331- list_del_init(&e->node);332332- serio_free_event(e);333333- }334334- }335335-336336- spin_unlock_irqrestore(&serio_event_lock, flags);337337-}338338-339339-340340-static struct serio_event *serio_get_event(void)341341-{342342- struct serio_event *event = NULL;343343- unsigned long flags;344344-345345- spin_lock_irqsave(&serio_event_lock, flags);346346-347347- if (!list_empty(&serio_event_list)) {348348- event = list_first_entry(&serio_event_list,349349- struct serio_event, node);350350- list_del_init(&event->node);351351- }352352-353353- spin_unlock_irqrestore(&serio_event_lock, flags);354354- return event;355355-}356356-357357-static void serio_handle_event(void)358358-{359359- struct serio_event *event;360360-361361- mutex_lock(&serio_mutex);362362-363363- while ((event = serio_get_event())) {364364-365365- switch (event->type) {366366-367367- case SERIO_REGISTER_PORT:368368- serio_add_port(event->object);369369- break;370370-371371- case SERIO_RECONNECT_PORT:372372- serio_reconnect_port(event->object);373373- break;374374-375375- case SERIO_RESCAN_PORT:376376- serio_disconnect_port(event->object);377377- serio_find_driver(event->object);378378- break;379379-380380- case SERIO_RECONNECT_SUBTREE:381381- serio_reconnect_subtree(event->object);382382- break;383383-384384- case SERIO_ATTACH_DRIVER:385385- serio_attach_driver(event->object);386386- break;387387- }388388-389389- serio_remove_duplicate_events(event);390390- serio_free_event(event);391391- }392392-393393- mutex_unlock(&serio_mutex);394220}395221396222/*···353355 spin_unlock_irqrestore(&serio_event_lock, flags);354356 return child;355357}356356-357357-static int serio_thread(void *nothing)358358-{359359- do {360360- serio_handle_event();361361- wait_event_interruptible(serio_wait,362362- kthread_should_stop() || !list_empty(&serio_event_list));363363- } while (!kthread_should_stop());364364-365365- return 0;366366-}367367-368358369359/*370360 * Serio port operations···10261040 return error;10271041 }1028104210291029- serio_task = kthread_run(serio_thread, NULL, "kseriod");10301030- if (IS_ERR(serio_task)) {10311031- bus_unregister(&serio_bus);10321032- error = PTR_ERR(serio_task);10331033- pr_err("Failed to start kseriod, error: %d\n", error);10341034- return error;10351035- }10361036-10371043 return 0;10381044}1039104510401046static void __exit serio_exit(void)10411047{10421048 bus_unregister(&serio_bus);10431043- kthread_stop(serio_task);10491049+10501050+ /*10511051+ * There should not be any outstanding events but work may10521052+ * still be scheduled so simply cancel it.10531053+ */10541054+ cancel_work_sync(&serio_event_work);10441055}1045105610461057subsys_initcall(serio_init);
+7-19
drivers/input/tablet/wacom_wac.c
···14141515#include "wacom_wac.h"1616#include "wacom.h"1717+#include <linux/input/mt.h>17181819static int wacom_penpartner_irq(struct wacom_wac *wacom)1920{···863862 struct wacom_features *features = &wacom->features;864863 struct input_dev *input = wacom->input;865864 unsigned char *data = wacom->data;866866- int sp = 0, sx = 0, sy = 0, count = 0;867865 int i;868866869867 for (i = 0; i < 2; i++) {870868 int p = data[9 * i + 2];869869+ bool touch = p && !wacom->shared->stylus_in_proximity;870870+871871 input_mt_slot(input, i);872872+ input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);872873 /*873874 * Touch events need to be disabled while stylus is874875 * in proximity because user's hand is resting on touchpad875876 * and sending unwanted events. User expects tablet buttons876877 * to continue working though.877878 */878878- if (p && !wacom->shared->stylus_in_proximity) {879879+ if (touch) {879880 int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff;880881 int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff;881882 if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {···887884 input_report_abs(input, ABS_MT_PRESSURE, p);888885 input_report_abs(input, ABS_MT_POSITION_X, x);889886 input_report_abs(input, ABS_MT_POSITION_Y, y);890890- if (wacom->id[i] < 0)891891- wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID;892892- if (!count++)893893- sp = p, sx = x, sy = y;894894- } else {895895- wacom->id[i] = -1;896887 }897897- input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]);898888 }899889900900- input_report_key(input, BTN_TOUCH, count > 0);901901- input_report_key(input, BTN_TOOL_FINGER, count == 1);902902- input_report_key(input, BTN_TOOL_DOUBLETAP, count == 2);903903-904904- input_report_abs(input, ABS_PRESSURE, sp);905905- input_report_abs(input, ABS_X, sx);906906- input_report_abs(input, ABS_Y, sy);890890+ input_mt_report_pointer_emulation(input, true);907891908892 input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);909893 input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);···12621272 __set_bit(BTN_TOOL_FINGER, input_dev->keybit);12631273 __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);1264127412651265- input_mt_create_slots(input_dev, 2);12751275+ input_mt_init_slots(input_dev, 2);12661276 input_set_abs_params(input_dev, ABS_MT_POSITION_X,12671277 0, features->x_max,12681278 features->x_fuzz, 0);···12721282 input_set_abs_params(input_dev, ABS_MT_PRESSURE,12731283 0, features->pressure_max,12741284 features->pressure_fuzz, 0);12751275- input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,12761276- MAX_TRACKING_ID, 0, 0);12771285 } else if (features->device_type == BTN_TOOL_PEN) {12781286 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);12791287 __set_bit(BTN_TOOL_PEN, input_dev->keybit);
-4
drivers/input/tablet/wacom_wac.h
···4242#define WACOM_QUIRK_MULTI_INPUT 0x00014343#define WACOM_QUIRK_BBTOUCH_LOWRES 0x000244444545-/* largest reported tracking id */4646-#define MAX_TRACKING_ID 0xfff4747-4845enum {4946 PENPARTNER = 0,5047 GRAPHIRE,···97100 int id[3];98101 __u32 serial[2];99102 int last_finger;100100- int trk_id;101103 struct wacom_features features;102104 struct wacom_shared *shared;103105 struct input_dev *input;
+22-10
drivers/input/touchscreen/Kconfig
···659659 To compile this driver as a module, choose M here: the660660 module will be called pcap_ts.661661662662+config TOUCHSCREEN_ST1232663663+ tristate "Sitronix ST1232 touchscreen controllers"664664+ depends on I2C665665+ help666666+ Say Y here if you want to support Sitronix ST1232667667+ touchscreen controller.668668+669669+ If unsure, say N.670670+671671+ To compile this driver as a module, choose M here: the672672+ module will be called st1232_ts.673673+674674+config TOUCHSCREEN_STMPE675675+ tristate "STMicroelectronics STMPE touchscreens"676676+ depends on MFD_STMPE677677+ help678678+ Say Y here if you want support for STMicroelectronics679679+ STMPE touchscreen controllers.680680+681681+ To compile this driver as a module, choose M here: the682682+ module will be called stmpe-ts.683683+662684config TOUCHSCREEN_TPS6507X663685 tristate "TPS6507x based touchscreens"664686 depends on I2C···692670693671 To compile this driver as a module, choose M here: the694672 module will be called tps6507x_ts.695695-696696-config TOUCHSCREEN_STMPE697697- tristate "STMicroelectronics STMPE touchscreens"698698- depends on MFD_STMPE699699- help700700- Say Y here if you want support for STMicroelectronics701701- STMPE touchscreen controllers.702702-703703- To compile this driver as a module, choose M here: the704704- module will be called stmpe-ts.705673706674endif
···1717 * Switch to grant tables together with xen-fbfront.c.1818 */19192020+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt2121+2022#include <linux/kernel.h>2123#include <linux/errno.h>2224#include <linux/module.h>···8684 input_report_key(dev, event->key.keycode,8785 event->key.pressed);8886 else8989- printk(KERN_WARNING9090- "xenkbd: unhandled keycode 0x%x\n",9191- event->key.keycode);8787+ pr_warning("unhandled keycode 0x%x\n",8888+ event->key.keycode);9289 break;9390 case XENKBD_TYPE_POS:9491 input_report_abs(dev, ABS_X, event->pos.abs_x);···293292 ret = xenbus_printf(XBT_NIL, info->xbdev->nodename,294293 "request-abs-pointer", "1");295294 if (ret)296296- printk(KERN_WARNING297297- "xenkbd: can't request abs-pointer");295295+ pr_warning("can't request abs-pointer\n");298296 }299297 xenbus_switch_state(dev, XenbusStateConnected);300298 break;
+8
drivers/macintosh/mac_hid.c
···23232424static struct input_dev *mac_hid_emumouse_dev;25252626+static DEFINE_MUTEX(mac_hid_emumouse_mutex);2727+2628static int mac_hid_create_emumouse(void)2729{2830 static struct lock_class_key mac_hid_emumouse_dev_event_class;···189187 int old_val = *valp;190188 int rc;191189190190+ rc = mutex_lock_killable(&mac_hid_emumouse_mutex);191191+ if (rc)192192+ return rc;193193+192194 rc = proc_dointvec(table, write, buffer, lenp, ppos);193195194196 if (rc == 0 && write && *valp != old_val) {···207201 /* Restore the old value in case of error */208202 if (rc)209203 *valp = old_val;204204+205205+ mutex_unlock(&mac_hid_emumouse_mutex);210206211207 return rc;212208}
+21-17
include/linux/input.h
···112112#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */113113#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */114114#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */115115+#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len) /* get device properties */115116116117#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global key state */117118#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */···128127#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */129128130129#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */130130+131131+/*132132+ * Device properties and quirks133133+ */134134+135135+#define INPUT_PROP_POINTER 0x00 /* needs a pointer */136136+#define INPUT_PROP_DIRECT 0x01 /* direct input devices */137137+#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */138138+#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */139139+140140+#define INPUT_PROP_MAX 0x1f141141+#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)131142132143/*133144 * Event types···771758#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */772759#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */773760#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */761761+#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */774762775763#ifdef __KERNEL__776764/* Implementation details, userspace should not care about these */777765#define ABS_MT_FIRST ABS_MT_TOUCH_MAJOR778778-#define ABS_MT_LAST ABS_MT_PRESSURE766766+#define ABS_MT_LAST ABS_MT_DISTANCE779767#endif780768781769#define ABS_MAX 0x3f···887873 */888874#define MT_TOOL_FINGER 0889875#define MT_TOOL_PEN 1876876+#define MT_TOOL_MAX 1890877891878/*892879 * Values describing the status of a force-feedback effect···11231108#include <linux/mod_devicetable.h>1124110911251110/**11261126- * struct input_mt_slot - represents the state of an input MT slot11271127- * @abs: holds current values of ABS_MT axes for this slot11281128- */11291129-struct input_mt_slot {11301130- int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];11311131-};11321132-11331133-/**11341111 * struct input_dev - represents an input device11351112 * @name: name of the device11361113 * @phys: physical path to the device in the system hierarchy11371114 * @uniq: unique identification code for the device (if device has it)11381115 * @id: id of the device (struct input_id)11161116+ * @propbit: bitmap of device properties and quirks11391117 * @evbit: bitmap of types of events supported by the device (EV_KEY,11401118 * EV_REL, etc.)11411119 * @keybit: bitmap of keys/buttons this device has···11631155 * of tracked contacts11641156 * @mtsize: number of MT slots the device uses11651157 * @slot: MT slot currently being transmitted11581158+ * @trkid: stores MT tracking ID for the current contact11661159 * @absinfo: array of &struct input_absinfo elements holding information11671160 * about absolute axes (current value, min, max, flat, fuzz,11681161 * resolution)···12121203 const char *uniq;12131204 struct input_id id;1214120512061206+ unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];12071207+12151208 unsigned long evbit[BITS_TO_LONGS(EV_CNT)];12161209 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];12171210 unsigned long relbit[BITS_TO_LONGS(REL_CNT)];···12501239 struct input_mt_slot *mt;12511240 int mtsize;12521241 int slot;12421242+ int trkid;1253124312541244 struct input_absinfo *absinfo;12551245···15001488 input_event(dev, EV_SYN, SYN_MT_REPORT, 0);15011489}1502149015031503-static inline void input_mt_slot(struct input_dev *dev, int slot)15041504-{15051505- input_event(dev, EV_ABS, ABS_MT_SLOT, slot);15061506-}15071507-15081491void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code);1509149215101493/**···1611160416121605int input_ff_create_memless(struct input_dev *dev, void *data,16131606 int (*play_effect)(struct input_dev *, void *, struct ff_effect *));16141614-16151615-int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots);16161616-void input_mt_destroy_slots(struct input_dev *dev);1617160716181608#endif16191609#endif
+59
include/linux/input/cma3000.h
···11+/*22+ * VTI CMA3000_Dxx Accelerometer driver33+ *44+ * Copyright (C) 2010 Texas Instruments55+ * Author: Hemanth V <hemanthv@ti.com>66+ *77+ * This program is free software; you can redistribute it and/or modify it88+ * under the terms of the GNU General Public License version 2 as published by99+ * the Free Software Foundation.1010+ *1111+ * This program is distributed in the hope that it will be useful, but WITHOUT1212+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1313+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1414+ * more details.1515+ *1616+ * You should have received a copy of the GNU General Public License along with1717+ * this program. If not, see <http://www.gnu.org/licenses/>.1818+ */1919+2020+#ifndef _LINUX_CMA3000_H2121+#define _LINUX_CMA3000_H2222+2323+#define CMAMODE_DEFAULT 02424+#define CMAMODE_MEAS100 12525+#define CMAMODE_MEAS400 22626+#define CMAMODE_MEAS40 32727+#define CMAMODE_MOTDET 42828+#define CMAMODE_FF100 52929+#define CMAMODE_FF400 63030+#define CMAMODE_POFF 73131+3232+#define CMARANGE_2G 20003333+#define CMARANGE_8G 80003434+3535+/**3636+ * struct cma3000_i2c_platform_data - CMA3000 Platform data3737+ * @fuzz_x: Noise on X Axis3838+ * @fuzz_y: Noise on Y Axis3939+ * @fuzz_z: Noise on Z Axis4040+ * @g_range: G range in milli g i.e 2000 or 80004141+ * @mode: Operating mode4242+ * @mdthr: Motion detect threshold value4343+ * @mdfftmr: Motion detect and free fall time value4444+ * @ffthr: Free fall threshold value4545+ */4646+4747+struct cma3000_platform_data {4848+ int fuzz_x;4949+ int fuzz_y;5050+ int fuzz_z;5151+ int g_range;5252+ uint8_t mode;5353+ uint8_t mdthr;5454+ uint8_t mdfftmr;5555+ uint8_t ffthr;5656+ unsigned long irqflags;5757+};5858+5959+#endif
+57
include/linux/input/mt.h
···11+#ifndef _INPUT_MT_H22+#define _INPUT_MT_H33+44+/*55+ * Input Multitouch Library66+ *77+ * Copyright (c) 2010 Henrik Rydberg88+ *99+ * This program is free software; you can redistribute it and/or modify it1010+ * under the terms of the GNU General Public License version 2 as published by1111+ * the Free Software Foundation.1212+ */1313+1414+#include <linux/input.h>1515+1616+#define TRKID_MAX 0xffff1717+1818+/**1919+ * struct input_mt_slot - represents the state of an input MT slot2020+ * @abs: holds current values of ABS_MT axes for this slot2121+ */2222+struct input_mt_slot {2323+ int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];2424+};2525+2626+static inline void input_mt_set_value(struct input_mt_slot *slot,2727+ unsigned code, int value)2828+{2929+ slot->abs[code - ABS_MT_FIRST] = value;3030+}3131+3232+static inline int input_mt_get_value(const struct input_mt_slot *slot,3333+ unsigned code)3434+{3535+ return slot->abs[code - ABS_MT_FIRST];3636+}3737+3838+int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots);3939+void input_mt_destroy_slots(struct input_dev *dev);4040+4141+static inline int input_mt_new_trkid(struct input_dev *dev)4242+{4343+ return dev->trkid++ & TRKID_MAX;4444+}4545+4646+static inline void input_mt_slot(struct input_dev *dev, int slot)4747+{4848+ input_event(dev, EV_ABS, ABS_MT_SLOT, slot);4949+}5050+5151+void input_mt_report_slot_state(struct input_dev *dev,5252+ unsigned int tool_type, bool active);5353+5454+void input_mt_report_finger_count(struct input_dev *dev, int count);5555+void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count);5656+5757+#endif