<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.linux.kernel.input">
    <title>gmane.linux.kernel.input</title>
    <link>http://blog.gmane.org/gmane.linux.kernel.input</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25337"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25335"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25314"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25311"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25304"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25303"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25287"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25284"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25282"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25277"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25274"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25268"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25265"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25264"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25261"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25260"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25257"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25255"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25250"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.kernel.input/25249"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25337">
    <title>(unknown)</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25337</link>
    <description>&lt;pre&gt;
 i am robothroli, Purchase manager from roli Merchant Ltd. We are
Import/export Company based in taiwan. We are interested in purchasing
your product and I would like to make an inquiry. Please inform me on:

Sample availability and price
Minimum order quantity
FOB Prices

Sincerely
Purchase Manager
robothroli



--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>robothroli company</dc:creator>
    <dc:date>2012-05-25T13:45:54</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25335">
    <title>HID Output and Feature Reports</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25335</link>
    <description>&lt;pre&gt;Hello all,

I'm working to support HID over GATT (HoG), which is HID over
Bluetooth Low Energy links, both on kernel and userspace. Traffic
coming from the remote peripheral through a L2CAP socket will be
handled in usespace, where the HID input reports are decapsulated from
GATT and injected back into the kernel through the new uHID module
written by David Herrmann. This module works similar to uinput, but
dealing with HID traffic.

The input part is working without problems and now I looking how to
support Output and Feature reports. Doing some basic testing it seems
we don't support Output reports very well. A basic use-case for that
is synchronizing keyboard leds (CAPS, NUM, etc) when there is more
than one keyboard connected, and I couldn't get this to work on my
tests. I didn't try to test feature reports since it's still not very
clear to me when they're used. The HID spec says that they exist for
setting values/controls on the peripheral that are not visible to the
user, but I haven't discovered any real-world use case for them. What
is the current state for these reports, do we support them somehow?

Also, I've found usbhid-dump by Greg K-H, but it doesn't seem to dump
data coming from the host to the device. Is this on the plans for this
tool? I can try to send a patch for it, if someone can guide me on how
this whole output/feature reports thing should work.

&lt;/pre&gt;</description>
    <dc:creator>Joao Paulo Rechi Vita</dc:creator>
    <dc:date>2012-05-25T20:51:28</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25314">
    <title>about input/hid</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25314</link>
    <description>&lt;pre&gt;hi all:
I have some questions about input/hid devices.
1. it seems only usb hid has reports_desc, why don't we put hid parse
in usbhid/hid-core.c instead of hid/hid-core.c?
2. at the end of mail is the report from mouse hid.
    i. where is the "USAGE_PAGE (Button) " defined, I cannot find
Button id in usage table.
    ii. REPORT_SIZE (1) always mean the unit is bit?
3. Spec seems only describe the value of the item mean, where I can
find the rules of the layout of the descriptor?

char ReportDescriptor[50] = {
02     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
03     0x09, 0x02,                    // USAGE (Mouse)
04     0xa1, 0x01,                    // COLLECTION (Application)
05     0x09, 0x01,                    //   USAGE (Pointer)
06     0xa1, 0x00,                    //   COLLECTION (Physical)
07     0x05, 0x09,                    //     USAGE_PAGE (Button)
08     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
09     0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
10     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
11     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
12     0x95, 0x03,                    //     REPORT_COUNT (3)
13     0x75, 0x01,                    //     REPORT_SIZE (1)
14     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
15     0x95, 0x01,                    //     REPORT_COUNT (1)
16     0x75, 0x05,                    //     REPORT_SIZE (5)
17     0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
18     0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
19     0x09, 0x30,                    //     USAGE (X)
20     0x09, 0x31,                    //     USAGE (Y)
21     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
22     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
23     0x75, 0x08,                    //     REPORT_SIZE (8)
24     0x95, 0x02,                    //     REPORT_COUNT (2)
25     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
26     0xc0,                          //   END_COLLECTION
27     0xc0                           // END_COLLECTION
28 };

Thanks for your help in advance,
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>loody</dc:creator>
    <dc:date>2012-05-24T13:38:51</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25311">
    <title>[git pull] Input updates for 3.5-rc0</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25311</link>
    <description>&lt;pre&gt;Hi Linus,

Please pull from:

git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus

to receive updates for the input subsystem. You will get:

- a bunch of new drivers (DA9052/53 touchscreenn controller, Synaptics
  Navpoint, LM8333 keypads, Wacom I2C touhscreen);
- updates to existing touchpad drivers (ALPS, Sntelic);
- Wacom driver now supports Intuos5;
- device-tree bindings in numerous drivers;
- other cleanups and fixes.

You will get a conflict in wacom_wac.c; please resolve taking "my"
chunks or let me know and I'll merge on my side.

Thanks!


Changelog:
---------

Ashish Jangam (1):
      Input: add support for DA9052/53 touch screen controller

Axel Lin (5):
      Input: serio - add helper macro for serio_driver boilerplate
      Input: serio - use module_serio_driver
      Input: gameport - add helper macro for gameport_driver boilerplate
      Input: gameport - use module_gameport_driver
      Input: use module_pci_driver

Daniel Kurtz (5):
      Input: atmel_mxt_ts - use CONFIG_PM_SLEEP
      Input: atmel_mxt_ts - only allow root to update firmware
      Input: atmel_mxt_ts - verify object size in mxt_write_object
      Input: atmel_mxt_ts - do not read extra (checksum) byte
      Input: atmel_mxt_ts - dump each message on just 1 line

Dmitry Torokhov (21):
      Input: xilinx_ps2 - allocate serio port separately
      Input: st1232 - switch to using SIMPLE_DEV_PM_OPS
      Input: wacom_i2c - do not use irq_to_gpio
      Input: ep93xx_keypad - switch to using dev_pm_ops
      Input: matrix-keypad - fix 'duplicate const' sparse warning
      Input: matrix-keypad - allocate keycodes with keypad structure
      Input: matrix-keypad - undo GPIO setup if input_register_device fails
      Input: cma3000-d0x - remove unneeded checks
      Input: tc3589x-keypad - remove unnecessary checks
      Input: serio_raw - ensure we don't block in non-blocking read
      Input: wacom - fix sparse warning
      Input: wacom - return proper error if usb_get_extra_descriptor() fails
      Input: wacom - use dev_xxx() instead of naked printk()s and dbg()s
      Input: serio_raw - signal EFAULT even if read/write partially succeeds
      Input: evdev - properly access RCU-protected 'grab' data
      Input: evdev - properly handle read/write with count 0
      Input: ALPS - switch to using input_mt_report_finger_count
      MAINTAINERS: adjust input-related patterns
      Input: matrix-keymap - uninline and prepare for device tree support
      Input: matrix-keymap - wire up device tree support
      Input: matrix-keymap - fix building keymaps

George Pantalos (1):
      Input: ALPS - add semi-MT support for v4 protocol

JJ Ding (1):
      Input: synaptics - fix compile warning

Jason Gerecke (4):
      Input: wacom - add basic Intuos5 support
      Input: wacom - add Intuos5 Touch Ring/ExpressKey support
      Input: wacom - add Intuos5 Touch Ring LED support
      Input: wacom - add Intuos5 multitouch sensor support

Jean-François Dagenais (1):
      Input: adp5588 - add support for gpio names

Jesper Juhl (1):
      Input: atkbd - fix language in a printed message

Julia Lawall (1):
      Input: aiptek - adjust error-handling code label

Magnus Damm (1):
      Input: st1232 - add device tree support

Paul Parsons (1):
      Input: Add Synaptics NavPoint (PXA27x SSP/SPI) driver

Peter Ujfalusi (1):
      Input: tl6040-vibra - Device Tree support

Ping Cheng (2):
      Input: wacom - retrieve maximum number of touch points
      Input: wacom - add 0xE5 (MT device) support

Poddar, Sourav (1):
      Input: omap-keypad - dynamically handle register offsets

Roland Stigge (2):
      Input: lpc32xx_ts - add device tree support
      Input: lpc32xx_ts - fix device tree compatible string

Shawn Landden (2):
      Input: usbtouchscreen - fix typo
      Input: usbtouchscreen - only expose e2i configure option in expert mode

Stephen Warren (1):
      Input: mpu3050 - set IRQF_ONESHOT when requesting the interrupt

Tai-hwa Liang (1):
      Input: sentelic - report device's production serial number

Tatsunosuke Tobita (1):
      Input: add support for Wacom Stylus device with I2C interface

Viresh Kumar (2):
      Input: spear-keyboard - add device tree bindings
      Input: spear-keyboard - document DT bindings

Wolfram Sang (1):
      Input: add support for LM8333 keypads


Diffstat:
--------

 Documentation/ABI/testing/sysfs-driver-wacom       |   15 +-
 .../devicetree/bindings/input/spear-keyboard.txt   |   20 +
 .../bindings/input/touchscreen/lpc32xx-tsc.txt     |   16 +
 .../devicetree/bindings/input/twl6040-vibra.txt    |   37 ++
 MAINTAINERS                                        |    2 +
 drivers/input/Kconfig                              |   17 +-
 drivers/input/Makefile                             |    2 +-
 drivers/input/evdev.c                              |   69 +++--
 drivers/input/gameport/emu10k1-gp.c                |   13 +-
 drivers/input/gameport/fm801-gp.c                  |   16 +-
 drivers/input/joystick/a3d.c                       |   13 +-
 drivers/input/joystick/adi.c                       |   17 +-
 drivers/input/joystick/cobra.c                     |   13 +-
 drivers/input/joystick/gf2k.c                      |   13 +-
 drivers/input/joystick/grip.c                      |   13 +-
 drivers/input/joystick/grip_mp.c                   |   13 +-
 drivers/input/joystick/guillemot.c                 |   13 +-
 drivers/input/joystick/interact.c                  |   13 +-
 drivers/input/joystick/joydump.c                   |   13 +-
 drivers/input/joystick/magellan.c                  |   17 +-
 drivers/input/joystick/sidewinder.c                |   13 +-
 drivers/input/joystick/spaceball.c                 |   17 +-
 drivers/input/joystick/spaceorb.c                  |   17 +-
 drivers/input/joystick/stinger.c                   |   17 +-
 drivers/input/joystick/tmdc.c                      |   13 +-
 drivers/input/joystick/twidjoy.c                   |   17 +-
 drivers/input/joystick/warrior.c                   |   17 +-
 drivers/input/joystick/zhenhua.c                   |   17 +-
 drivers/input/keyboard/Kconfig                     |   32 ++-
 drivers/input/keyboard/Makefile                    |    1 +
 drivers/input/keyboard/adp5588-keys.c              |    1 +
 drivers/input/keyboard/atkbd.c                     |    2 +-
 drivers/input/keyboard/ep93xx_keypad.c             |   44 +--
 drivers/input/keyboard/hil_kbd.c                   |   13 +-
 drivers/input/keyboard/imx_keypad.c                |   17 +-
 drivers/input/keyboard/lkkbd.c                     |   17 +-
 drivers/input/keyboard/lm8333.c                    |  235 +++++++++++++
 drivers/input/keyboard/matrix_keypad.c             |   99 +++---
 drivers/input/keyboard/newtonkbd.c                 |   13 +-
 drivers/input/keyboard/nomadik-ske-keypad.c        |   20 +-
 drivers/input/keyboard/omap-keypad.c               |   20 +-
 drivers/input/keyboard/omap4-keypad.c              |  133 ++++++--
 drivers/input/keyboard/pmic8xxx-keypad.c           |   20 +-
 drivers/input/keyboard/samsung-keypad.c            |   20 +-
 drivers/input/keyboard/spear-keyboard.c            |   92 ++++--
 drivers/input/keyboard/stmpe-keypad.c              |   16 +-
 drivers/input/keyboard/stowaway.c                  |   13 +-
 drivers/input/keyboard/sunkbd.c                    |   17 +-
 drivers/input/keyboard/tc3589x-keypad.c            |   41 +--
 drivers/input/keyboard/tca8418_keypad.c            |   15 +-
 drivers/input/keyboard/tegra-kbc.c                 |   68 +++--
 drivers/input/keyboard/tnetv107x-keypad.c          |   21 +-
 drivers/input/keyboard/twl4030_keypad.c            |   25 +-
 drivers/input/keyboard/w90p910_keypad.c            |   27 +-
 drivers/input/keyboard/xtkbd.c                     |   13 +-
 drivers/input/matrix-keymap.c                      |  163 +++++++++
 drivers/input/misc/cma3000_d0x.c                   |    2 +-
 drivers/input/misc/mpu3050.c                       |    2 +-
 drivers/input/misc/twl6040-vibra.c                 |   46 ++-
 drivers/input/mouse/Kconfig                        |   12 +
 drivers/input/mouse/Makefile                       |    1 +
 drivers/input/mouse/alps.c                         |   81 ++++-
 drivers/input/mouse/alps.h                         |    2 +
 drivers/input/mouse/navpoint.c                     |  369 +++++++++++++++++++
 drivers/input/mouse/sentelic.c                     |   34 ++-
 drivers/input/mouse/sentelic.h                     |    8 +
 drivers/input/mouse/sermouse.c                     |   13 +-
 drivers/input/mouse/synaptics.c                    |   20 +-
 drivers/input/mouse/vsxxxaa.c                      |   14 +-
 drivers/input/of_keymap.c                          |   87 -----
 drivers/input/serio/pcips2.c                       |   15 +-
 drivers/input/serio/ps2mult.c                      |   13 +-
 drivers/input/serio/serio_raw.c                    |   65 ++--
 drivers/input/serio/xilinx_ps2.c                   |   35 +-
 drivers/input/tablet/aiptek.c                      |    2 +-
 drivers/input/tablet/wacom.h                       |    4 +-
 drivers/input/tablet/wacom_sys.c                   |  244 ++++++++++----
 drivers/input/tablet/wacom_wac.c                   |  298 ++++++++++++++--
 drivers/input/tablet/wacom_wac.h                   |   13 +
 drivers/input/touchscreen/Kconfig                  |   34 ++-
 drivers/input/touchscreen/Makefile                 |    2 +
 drivers/input/touchscreen/atmel_mxt_ts.c           |   33 +--
 drivers/input/touchscreen/da9052_tsi.c             |  370 ++++++++++++++++++++
 drivers/input/touchscreen/dynapro.c                |   17 +-
 drivers/input/touchscreen/elo.c                    |   17 +-
 drivers/input/touchscreen/fujitsu_ts.c             |   13 +-
 drivers/input/touchscreen/gunze.c                  |   17 +-
 drivers/input/touchscreen/h3600_ts_input.c         |   17 +-
 drivers/input/touchscreen/hampshire.c              |   17 +-
 drivers/input/touchscreen/inexio.c                 |   17 +-
 drivers/input/touchscreen/lpc32xx_ts.c             |   10 +
 drivers/input/touchscreen/mtouch.c                 |   17 +-
 drivers/input/touchscreen/penmount.c               |   17 +-
 drivers/input/touchscreen/st1232.c                 |   20 +-
 drivers/input/touchscreen/touchit213.c             |   17 +-
 drivers/input/touchscreen/touchright.c             |   17 +-
 drivers/input/touchscreen/touchwin.c               |   17 +-
 drivers/input/touchscreen/tsc40.c                  |   12 +-
 drivers/input/touchscreen/wacom_i2c.c              |  282 +++++++++++++++
 drivers/input/touchscreen/wacom_w8001.c            |   13 +-
 include/linux/gameport.h                           |   13 +
 include/linux/i2c/adp5588.h                        |    1 +
 include/linux/input/lm8333.h                       |   24 ++
 include/linux/input/matrix_keypad.h                |   54 +---
 include/linux/input/navpoint.h                     |   12 +
 include/linux/serio.h                              |   13 +
 106 files changed, 2845 insertions(+), 1299 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/spear-keyboard.txt
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/lpc32xx-tsc.txt
 create mode 100644 Documentation/devicetree/bindings/input/twl6040-vibra.txt
 create mode 100644 drivers/input/keyboard/lm8333.c
 create mode 100644 drivers/input/matrix-keymap.c
 create mode 100644 drivers/input/mouse/navpoint.c
 delete mode 100644 drivers/input/of_keymap.c
 create mode 100644 drivers/input/touchscreen/da9052_tsi.c
 create mode 100644 drivers/input/touchscreen/wacom_i2c.c
 create mode 100644 include/linux/input/lm8333.h
 create mode 100644 include/linux/input/navpoint.h

&lt;/pre&gt;</description>
    <dc:creator>Dmitry Torokhov</dc:creator>
    <dc:date>2012-05-24T08:32:16</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25304">
    <title>[PATCH v5] input: Add MELFAS mms114 touchscreen driver</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25304</link>
    <description>&lt;pre&gt;This is a initial driver for new touchscreen chip mms114 of MELFAS.
It uses I2C interface and supports 10 multi touch.

Signed-off-by: Joonyoung Shim &amp;lt;jy0922.shim&amp;lt; at &amp;gt;samsung.com&amp;gt;
Signed-off-by: Kyungmin Park &amp;lt;kyungmin.park&amp;lt; at &amp;gt;samsung.com&amp;gt;
---
This v5 patch was updated from Henrik review mainly.

Changelog

from v1:
- Remove mutex and use one i2c_transfer() to read registers
- Use input_mt_report_pointer_emulation() and optimized input report
- Add ABS_MT_PRESSURE report
- Add core regulator control

from v2:
- Use BUG() when try to read MMS114_MODE_CONTROL
- Move i2c delay code
- Remove too much initialzation in declaration in mms114_proc_mt()
- Fix packet size check
- Use "error" instead of "ret"
- Add open and close function including regulator configuration
- Use module_i2c_driver()

from v3:
- Use check input_dev-&amp;gt;users in PM functions

from v4:
- Modify MMS114_PACKET_NUM to 8 for latest firmware
- Define struct mms114_touch
- Some code clean

Thanks.

 drivers/input/touchscreen/Kconfig  |   12 +
 drivers/input/touchscreen/Makefile |    1 +
 drivers/input/touchscreen/mms114.c |  565 ++++++++++++++++++++++++++++++++++++
 include/linux/i2c/mms114.h         |   24 ++
 4 files changed, 602 insertions(+), 0 deletions(-)
 create mode 100644 drivers/input/touchscreen/mms114.c
 create mode 100644 include/linux/i2c/mms114.h

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 2a21419..3486795 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -340,6 +340,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config TOUCHSCREEN_MCS5000
   To compile this driver as a module, choose M here: the
   module will be called mcs5000_ts.
 
+config TOUCHSCREEN_MMS114
+tristate "MELFAS MMS114 touchscreen"
+depends on I2C
+help
+  Say Y here if you have the MELFAS MMS114 touchscreen controller
+  chip in your system.
+
+  If unsure, say N.
+
+  To compile this driver as a module, choose M here: the
+  module will be called mms114.
+
 config TOUCHSCREEN_MTOUCH
 tristate "MicroTouch serial touchscreens"
 select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 3d5cf8c..882da14 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -36,6 +36,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; obj-$(CONFIG_TOUCHSCREEN_LPC32XX)+= lpc32xx_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MAX11801)+= max11801_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MC13783)+= mc13783_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MCS5000)+= mcs5000_ts.o
+obj-$(CONFIG_TOUCHSCREEN_MMS114)+= mms114.o
 obj-$(CONFIG_TOUCHSCREEN_MIGOR)+= migor_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MTOUCH)+= mtouch.o
 obj-$(CONFIG_TOUCHSCREEN_MK712)+= mk712.o
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
new file mode 100644
index 0000000..616f463
--- /dev/null
+++ b/drivers/input/touchscreen/mms114.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,565 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim &amp;lt;jy0922.shim&amp;lt; at &amp;gt;samsung.com&amp;gt;
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundationr
+ */
+
+#include &amp;lt;linux/module.h&amp;gt;
+#include &amp;lt;linux/init.h&amp;gt;
+#include &amp;lt;linux/delay.h&amp;gt;
+#include &amp;lt;linux/i2c.h&amp;gt;
+#include &amp;lt;linux/i2c/mms114.h&amp;gt;
+#include &amp;lt;linux/input/mt.h&amp;gt;
+#include &amp;lt;linux/interrupt.h&amp;gt;
+#include &amp;lt;linux/regulator/consumer.h&amp;gt;
+#include &amp;lt;linux/slab.h&amp;gt;
+
+/* Write only registers */
+#define MMS114_MODE_CONTROL0x01
+#define MMS114_OPERATION_MODE_MASK0xE
+#define MMS114_ACTIVE(1 &amp;lt;&amp;lt; 1)
+
+#define MMS114_XY_RESOLUTION_H0x02
+#define MMS114_X_RESOLUTION0x03
+#define MMS114_Y_RESOLUTION0x04
+#define MMS114_CONTACT_THRESHOLD0x05
+#define MMS114_MOVING_THRESHOLD0x06
+
+/* Read only registers */
+#define MMS114_PACKET_SIZE0x0F
+#define MMS114_INFOMATION0x10
+#define MMS114_TSP_REV0xF0
+
+/* Minimum delay time is 50us between stop and start signal of i2c */
+#define MMS114_I2C_DELAY50
+
+/* 200ms needs after power on */
+#define MMS114_POWERON_DELAY200
+
+/* Touchscreen absolute values */
+#define MMS114_MAX_AREA0xff
+
+#define MMS114_MAX_TOUCH10
+#define MMS114_PACKET_NUM8
+
+/* Touch type */
+#define MMS114_TYPE_NONE0
+#define MMS114_TYPE_TOUCHSCREEN1
+#define MMS114_TYPE_TOUCHKEY2
+
+struct mms114_data {
+struct i2c_client*client;
+struct input_dev*input_dev;
+struct regulator*core_reg;
+struct regulator*io_reg;
+struct mutexmutex;
+boolenabled;
+const struct mms114_platform_data*pdata;
+
+/* Use cache data for mode control register(write only) */
+u8cache_mode_control;
+};
+
+struct mms114_touch {
+u8 id:4, reserved_bit4:1, type:2, pressed:1;
+u8 x_hi:4, y_hi:4;
+u8 x_lo;
+u8 y_lo;
+u8 width;
+u8 strength;
+u8 reserved[2];
+} __packed;
+
+static int __mms114_read_reg(struct mms114_data *data, unsigned int reg,
+     unsigned int len, u8 *val)
+{
+struct i2c_client *client = data-&amp;gt;client;
+struct i2c_msg xfer[2];
+u8 buf = reg &amp;amp; 0xff;
+int error;
+
+if ((reg &amp;lt;= MMS114_MODE_CONTROL) &amp;amp;&amp;amp; (reg + len &amp;gt; MMS114_MODE_CONTROL)) {
+BUG();
+return -EINVAL;
+}
+
+/* Write register: use repeated start */
+xfer[0].addr = client-&amp;gt;addr;
+xfer[0].flags = I2C_M_TEN | I2C_M_NOSTART;
+xfer[0].len = 1;
+xfer[0].buf = &amp;amp;buf;
+
+/* Read data */
+xfer[1].addr = client-&amp;gt;addr;
+xfer[1].flags = I2C_M_RD;
+xfer[1].len = len;
+xfer[1].buf = val;
+
+error = i2c_transfer(client-&amp;gt;adapter, xfer, 2);
+if (error != 2) {
+dev_err(&amp;amp;client-&amp;gt;dev, "%s: i2c transfer failed (%d)\n",
+__func__, error);
+return error &amp;lt; 0 ? error : -EIO;
+}
+udelay(MMS114_I2C_DELAY);
+
+return 0;
+}
+
+static int mms114_read_reg(struct mms114_data *data, unsigned int reg)
+{
+u8 val;
+int error;
+
+if (reg == MMS114_MODE_CONTROL)
+return data-&amp;gt;cache_mode_control;
+
+error = __mms114_read_reg(data, reg, 1, &amp;amp;val);
+return error &amp;lt; 0 ? error : val;
+}
+
+static int mms114_write_reg(struct mms114_data *data, unsigned int reg,
+    unsigned int val)
+{
+struct i2c_client *client = data-&amp;gt;client;
+u8 buf[2];
+int error;
+
+buf[0] = reg &amp;amp; 0xff;
+buf[1] = val &amp;amp; 0xff;
+
+error = i2c_master_send(client, buf, 2);
+if (error != 2) {
+dev_err(&amp;amp;client-&amp;gt;dev, "%s, i2c send failed (%d)\n", __func__,
+error);
+return error &amp;lt; 0 ? error : -EIO;
+}
+udelay(MMS114_I2C_DELAY);
+
+if (reg == MMS114_MODE_CONTROL)
+data-&amp;gt;cache_mode_control = val;
+
+return 0;
+}
+
+static void mms114_proc_mt(struct mms114_data *data, struct mms114_touch *touch)
+{
+const struct mms114_platform_data *pdata = data-&amp;gt;pdata;
+struct i2c_client *client = data-&amp;gt;client;
+struct input_dev *input_dev = data-&amp;gt;input_dev;
+unsigned int id;
+unsigned int x;
+unsigned int y;
+
+if (touch-&amp;gt;id &amp;gt; MMS114_MAX_TOUCH) {
+dev_err(&amp;amp;client-&amp;gt;dev, "Wrong touch id (%d)\n", touch-&amp;gt;id);
+return;
+}
+
+if (touch-&amp;gt;type != MMS114_TYPE_TOUCHSCREEN) {
+dev_err(&amp;amp;client-&amp;gt;dev, "Wrong touch type (%d)\n", touch-&amp;gt;type);
+return;
+}
+
+id = touch-&amp;gt;id - 1;
+x = touch-&amp;gt;x_lo | touch-&amp;gt;x_hi &amp;lt;&amp;lt; 8;
+y = touch-&amp;gt;y_lo | touch-&amp;gt;y_hi &amp;lt;&amp;lt; 8;
+if (x &amp;gt; pdata-&amp;gt;x_size || y &amp;gt; pdata-&amp;gt;y_size) {
+dev_err(&amp;amp;client-&amp;gt;dev, "Wrong touch coordinates (%d, %d)\n",
+x, y);
+return;
+}
+
+if (pdata-&amp;gt;x_invert)
+x = pdata-&amp;gt;x_size - x;
+if (pdata-&amp;gt;y_invert)
+y = pdata-&amp;gt;y_size - y;
+
+dev_dbg(&amp;amp;client-&amp;gt;dev, "id: %d, type: %d, pressed: %d\n",
+id, touch-&amp;gt;type, touch-&amp;gt;pressed);
+dev_dbg(&amp;amp;client-&amp;gt;dev, "x: %d, y: %d, width: %d, strength: %d\n",
+x, y, touch-&amp;gt;width, touch-&amp;gt;strength);
+
+input_mt_slot(input_dev, id);
+input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, touch-&amp;gt;pressed);
+
+if (touch-&amp;gt;pressed) {
+input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, touch-&amp;gt;width);
+input_report_abs(input_dev, ABS_MT_POSITION_X, x);
+input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
+input_report_abs(input_dev, ABS_MT_PRESSURE, touch-&amp;gt;strength);
+}
+}
+
+static irqreturn_t mms114_interrupt(int irq, void *dev_id)
+{
+struct mms114_data *data = dev_id;
+struct mms114_touch touch[MMS114_MAX_TOUCH];
+int packet_size;
+int touch_size;
+int index;
+int error;
+
+if (!data-&amp;gt;enabled)
+goto out;
+
+packet_size = mms114_read_reg(data, MMS114_PACKET_SIZE);
+if (packet_size &amp;lt;= 0)
+goto out;
+
+touch_size = packet_size / MMS114_PACKET_NUM;
+
+error = __mms114_read_reg(data, MMS114_INFOMATION, packet_size,
+(u8 *)touch);
+if (error &amp;lt; 0)
+goto out;
+
+for (index = 0; index &amp;lt; touch_size; index++)
+mms114_proc_mt(data, touch + index);
+
+input_mt_report_pointer_emulation(data-&amp;gt;input_dev, true);
+input_sync(data-&amp;gt;input_dev);
+
+out:
+return IRQ_HANDLED;
+}
+
+static int mms114_set_active(struct mms114_data *data, bool active)
+{
+int val;
+
+val = mms114_read_reg(data, MMS114_MODE_CONTROL);
+if (val &amp;lt; 0)
+return val;
+
+val &amp;amp;= ~MMS114_OPERATION_MODE_MASK;
+
+/* If active is false, sleep mode */
+if (active)
+val |= MMS114_ACTIVE;
+
+return mms114_write_reg(data, MMS114_MODE_CONTROL, val);
+}
+
+static int mms114_get_version(struct mms114_data *data)
+{
+struct device *dev = &amp;amp;data-&amp;gt;client-&amp;gt;dev;
+u8 buf[6];
+int error;
+
+error = __mms114_read_reg(data, MMS114_TSP_REV, 6, buf);
+if (error &amp;lt; 0)
+return error;
+
+dev_info(dev, "TSP Rev: 0x%x, HW Rev: 0x%x, Firmware Ver: 0x%x\n",
+buf[0], buf[1], buf[3]);
+
+return 0;
+}
+
+static int mms114_setup_regs(struct mms114_data *data)
+{
+const struct mms114_platform_data *pdata = data-&amp;gt;pdata;
+int val;
+int error;
+
+error = mms114_set_active(data, true);
+if (error &amp;lt; 0)
+return error;
+
+val = (pdata-&amp;gt;x_size &amp;gt;&amp;gt; 8) &amp;amp; 0xf;
+val |= ((pdata-&amp;gt;y_size &amp;gt;&amp;gt; 8) &amp;amp; 0xf) &amp;lt;&amp;lt; 4;
+error = mms114_write_reg(data, MMS114_XY_RESOLUTION_H, val);
+if (error &amp;lt; 0)
+return error;
+
+val = pdata-&amp;gt;x_size &amp;amp; 0xff;
+error = mms114_write_reg(data, MMS114_X_RESOLUTION, val);
+if (error &amp;lt; 0)
+return error;
+
+val = pdata-&amp;gt;y_size &amp;amp; 0xff;
+error = mms114_write_reg(data, MMS114_Y_RESOLUTION, val);
+if (error &amp;lt; 0)
+return error;
+
+if (pdata-&amp;gt;contact_threshold) {
+error = mms114_write_reg(data, MMS114_CONTACT_THRESHOLD,
+pdata-&amp;gt;contact_threshold);
+if (error &amp;lt; 0)
+return error;
+}
+
+if (pdata-&amp;gt;moving_threshold) {
+error = mms114_write_reg(data, MMS114_MOVING_THRESHOLD,
+pdata-&amp;gt;moving_threshold);
+if (error &amp;lt; 0)
+return error;
+}
+
+return 0;
+}
+
+static int mms114_start(struct mms114_data *data)
+{
+int error;
+
+mutex_lock(&amp;amp;data-&amp;gt;mutex);
+if (data-&amp;gt;enabled)
+goto out;
+
+if (data-&amp;gt;core_reg)
+regulator_enable(data-&amp;gt;core_reg);
+if (data-&amp;gt;io_reg)
+regulator_enable(data-&amp;gt;io_reg);
+mdelay(MMS114_POWERON_DELAY);
+
+error = mms114_setup_regs(data);
+if (error &amp;lt; 0) {
+mutex_unlock(&amp;amp;data-&amp;gt;mutex);
+return error;
+}
+
+data-&amp;gt;enabled = true;
+
+out:
+mutex_unlock(&amp;amp;data-&amp;gt;mutex);
+return 0;
+}
+
+static void mms114_stop(struct mms114_data *data)
+{
+mutex_lock(&amp;amp;data-&amp;gt;mutex);
+if (!data-&amp;gt;enabled)
+goto out;
+
+if (data-&amp;gt;io_reg)
+regulator_disable(data-&amp;gt;io_reg);
+if (data-&amp;gt;core_reg)
+regulator_disable(data-&amp;gt;core_reg);
+
+data-&amp;gt;enabled = false;
+
+out:
+mutex_unlock(&amp;amp;data-&amp;gt;mutex);
+}
+
+static int mms114_input_open(struct input_dev *dev)
+{
+struct mms114_data *data = input_get_drvdata(dev);
+
+return mms114_start(data);
+}
+
+static void mms114_input_close(struct input_dev *dev)
+{
+struct mms114_data *data = input_get_drvdata(dev);
+
+mms114_stop(data);
+}
+
+static int __devinit mms114_probe(struct i2c_client *client,
+  const struct i2c_device_id *id)
+{
+struct mms114_data *data;
+struct input_dev *input_dev;
+int error;
+
+if (!client-&amp;gt;dev.platform_data) {
+dev_err(&amp;amp;client-&amp;gt;dev, "Need platform data\n");
+return -EINVAL;
+}
+
+if (!i2c_check_functionality(client-&amp;gt;adapter,
+I2C_FUNC_PROTOCOL_MANGLING)) {
+dev_err(&amp;amp;client-&amp;gt;dev,
+"Need i2c bus that supports protocol mangling\n");
+return -ENODEV;
+}
+
+data = kzalloc(sizeof(struct mms114_data), GFP_KERNEL);
+input_dev = input_allocate_device();
+if (!data || !input_dev) {
+dev_err(&amp;amp;client-&amp;gt;dev, "Failed to allocate memory\n");
+error = -ENOMEM;
+goto err_free_mem;
+}
+
+mutex_init(&amp;amp;data-&amp;gt;mutex);
+
+data-&amp;gt;client = client;
+data-&amp;gt;input_dev = input_dev;
+data-&amp;gt;pdata = client-&amp;gt;dev.platform_data;
+
+input_dev-&amp;gt;name = "MELPAS MMS114 Touchscreen";
+input_dev-&amp;gt;id.bustype = BUS_I2C;
+input_dev-&amp;gt;dev.parent = &amp;amp;client-&amp;gt;dev;
+input_dev-&amp;gt;open = mms114_input_open;
+input_dev-&amp;gt;close = mms114_input_close;
+
+__set_bit(EV_ABS, input_dev-&amp;gt;evbit);
+__set_bit(EV_KEY, input_dev-&amp;gt;evbit);
+__set_bit(BTN_TOUCH, input_dev-&amp;gt;keybit);
+input_set_abs_params(input_dev, ABS_X, 0, data-&amp;gt;pdata-&amp;gt;x_size, 0, 0);
+input_set_abs_params(input_dev, ABS_Y, 0, data-&amp;gt;pdata-&amp;gt;y_size, 0, 0);
+
+/* For multi touch */
+input_mt_init_slots(input_dev, MMS114_MAX_TOUCH);
+input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+     0, MMS114_MAX_AREA, 0, 0);
+input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+     0, data-&amp;gt;pdata-&amp;gt;x_size, 0, 0);
+input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+     0, data-&amp;gt;pdata-&amp;gt;y_size, 0, 0);
+input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
+
+input_set_drvdata(input_dev, data);
+i2c_set_clientdata(client, data);
+
+data-&amp;gt;core_reg = regulator_get(&amp;amp;client-&amp;gt;dev, "avdd");
+if (IS_ERR(data-&amp;gt;core_reg)) {
+error = PTR_ERR(data-&amp;gt;core_reg);
+dev_err(&amp;amp;client-&amp;gt;dev, "Unable to get the Core regulator (%d)\n",
+error);
+goto err_free_mem;
+}
+
+data-&amp;gt;io_reg = regulator_get(&amp;amp;client-&amp;gt;dev, "vdd");
+if (IS_ERR(data-&amp;gt;io_reg)) {
+error = PTR_ERR(data-&amp;gt;io_reg);
+dev_err(&amp;amp;client-&amp;gt;dev, "Unable to get the IO regulator (%d)\n",
+error);
+goto err_core_reg;
+}
+
+error = mms114_start(data);
+if (error &amp;lt; 0)
+goto err_io_reg;
+
+error = mms114_get_version(data);
+if (error &amp;lt; 0)
+goto err_io_reg;
+
+mms114_stop(data);
+
+error = request_threaded_irq(client-&amp;gt;irq, NULL, mms114_interrupt,
+IRQF_TRIGGER_FALLING, "mms114", data);
+if (error &amp;lt; 0) {
+dev_err(&amp;amp;client-&amp;gt;dev, "Failed to register interrupt\n");
+goto err_io_reg;
+}
+
+error = input_register_device(data-&amp;gt;input_dev);
+if (error &amp;lt; 0)
+goto err_free_irq;
+
+if (data-&amp;gt;pdata-&amp;gt;cfg_pin)
+data-&amp;gt;pdata-&amp;gt;cfg_pin(true);
+
+return 0;
+
+err_free_irq:
+free_irq(client-&amp;gt;irq, data);
+err_io_reg:
+regulator_put(data-&amp;gt;io_reg);
+err_core_reg:
+regulator_put(data-&amp;gt;core_reg);
+err_free_mem:
+input_free_device(input_dev);
+kfree(data);
+return error;
+}
+
+static int __devexit mms114_remove(struct i2c_client *client)
+{
+struct mms114_data *data = i2c_get_clientdata(client);
+
+free_irq(client-&amp;gt;irq, data);
+regulator_put(data-&amp;gt;io_reg);
+regulator_put(data-&amp;gt;core_reg);
+input_unregister_device(data-&amp;gt;input_dev);
+kfree(data);
+
+return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mms114_suspend(struct device *dev)
+{
+struct i2c_client *client = to_i2c_client(dev);
+struct mms114_data *data = i2c_get_clientdata(client);
+struct input_dev *input_dev = data-&amp;gt;input_dev;
+int id;
+
+disable_irq(client-&amp;gt;irq);
+
+/* Release all touch */
+for (id = 0; id &amp;lt; MMS114_MAX_TOUCH; id++) {
+input_mt_slot(input_dev, id);
+input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
+}
+
+input_mt_report_pointer_emulation(input_dev, true);
+input_sync(input_dev);
+
+mms114_stop(data);
+
+if (data-&amp;gt;pdata-&amp;gt;cfg_pin)
+data-&amp;gt;pdata-&amp;gt;cfg_pin(false);
+
+return 0;
+}
+
+static int mms114_resume(struct device *dev)
+{
+struct i2c_client *client = to_i2c_client(dev);
+struct mms114_data *data = i2c_get_clientdata(client);
+struct input_dev *input_dev = data-&amp;gt;input_dev;
+int error;
+
+if (data-&amp;gt;pdata-&amp;gt;cfg_pin)
+data-&amp;gt;pdata-&amp;gt;cfg_pin(true);
+
+mutex_lock(&amp;amp;input_dev-&amp;gt;mutex);
+if (input_dev-&amp;gt;users) {
+error = mms114_start(data);
+if (error &amp;lt; 0) {
+mutex_unlock(&amp;amp;input_dev-&amp;gt;mutex);
+return error;
+}
+}
+mutex_unlock(&amp;amp;input_dev-&amp;gt;mutex);
+
+enable_irq(client-&amp;gt;irq);
+return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mms114_pm_ops, mms114_suspend, mms114_resume);
+
+static const struct i2c_device_id mms114_id[] = {
+{ "mms114", 0 },
+{ }
+};
+MODULE_DEVICE_TABLE(i2c, mms114_id);
+
+static struct i2c_driver mms114_driver = {
+.driver = {
+.name= "mms114",
+.owner= THIS_MODULE,
+.pm= &amp;amp;mms114_pm_ops,
+},
+.probe= mms114_probe,
+.remove= __devexit_p(mms114_remove),
+.id_table= mms114_id,
+};
+
+module_i2c_driver(mms114_driver);
+
+/* Module information */
+MODULE_AUTHOR("Joonyoung Shim &amp;lt;jy0922.shim&amp;lt; at &amp;gt;samsung.com&amp;gt;");
+MODULE_DESCRIPTION("MELFAS mms114 Touchscreen driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/i2c/mms114.h b/include/linux/i2c/mms114.h
new file mode 100644
index 0000000..5722ebf
--- /dev/null
+++ b/include/linux/i2c/mms114.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,24 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim &amp;lt;jy0922.shim&amp;lt; at &amp;gt;samsung.com&amp;gt;
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundationr
+ */
+
+#ifndef __LINUX_MMS114_H
+#define __LINUX_MMS114_H
+
+struct mms114_platform_data {
+unsigned int x_size;
+unsigned int y_size;
+unsigned int contact_threshold;
+unsigned int moving_threshold;
+bool x_invert;
+bool y_invert;
+
+void (*cfg_pin)(bool);
+};
+
+#endif/* __LINUX_MMS114_H */
&lt;/pre&gt;</description>
    <dc:creator>Joonyoung Shim</dc:creator>
    <dc:date>2012-05-24T06:37:47</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25303">
    <title>Reg. kernel crash while using pixcir touchscreen driver</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25303</link>
    <description>&lt;pre&gt;Hi,

I encountered a kernel crash while integrating Pixcir touchscreen
driver with one of our hardware. The log is attached at the end of the
mail (inline).

The following ISR code:

while (!tsdata-&amp;gt;exiting) {
        pixcir_ts_poscheck(tsdata);

        if (tsdata-&amp;gt;chip-&amp;gt;attb_read_val())
              break;

        msleep(20);
}

seems to run until the if condition is false. However, when it exits
the loop (when the condition becomes true), it crashes saying "exiting
task "irq/438-pixcir_" (1011) is an active IRQ thread".

I have 2 questions here:
1. Do we need such a loop and the if condition. In my case it worked
with the isr just doing
pixcir_ts_poscheck(tsdata);

2. What exactly is expected by attb_read_val() function.

Any pointers would be helpful.

*****
Unable to handle kernel paging request at virtual address e7fddef0
pgd = cf9e4000
[e7fddef0] *pgd=00000000
Internal error: Oops: 80000005 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 1    Not tainted  (3.4.0-rc3-00050-g718e84c-dirty #24)
PC is at 0xe7fddef0
LR is at pixcir_ts_isr+0x7c/0x210
pc : [&amp;lt;e7fddef0&amp;gt;]    lr : [&amp;lt;c01aaa68&amp;gt;]    psr: 60000013
sp : cef83f50  ip : 00000000  fp : 00000001
r10: cf8ce780  r9 : 00000001  r8 : 00000000
r7 : 00000000  r6 : 00000000  r5 : 00000000  r4 : 000000fc
r3 : e7fddef0  r2 : cef83f48  r1 : 60000013  r0 : 00000000
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 10c5387d  Table: 4f9e404a  DAC: 00000015
Process irq/438-pixcir_ (pid: 1011, stack limit = 0xcef822f0)
Stack: (0xcef83f50 to 0xcef84000)
3f40:                                     cef83f8c 00000256 c0367f80 56000180
3f60: 0000fc02 00000000 00000001 cef82000 cebdc720 00000001 cebdc700 c0380a40
3f80: c0380a94 c038c670 00000000 c00636e8 c0367f80 c03672c0 00000001 cf833dfc
3fa0: cebdc700 c00635ec 00000013 00000000 00000000 00000000 00000000 c0038bd4
3fc0: 00000000 cebdc700 00000000 00000000 00000000 dead4ead ffffffff ffffffff
3fe0: cef83fe0 cef83fe0 cf833dfc c0038b50 c000f02c c000f02c 00002468 00000000
[&amp;lt;c01aaa68&amp;gt;] (pixcir_ts_isr+0x7c/0x210) from [&amp;lt;c00636e8&amp;gt;]
(irq_thread+0xfc/0x14c)
[&amp;lt;c00636e8&amp;gt;] (irq_thread+0xfc/0x14c) from [&amp;lt;c0038bd4&amp;gt;] (kthread+0x84/0x90)
[&amp;lt;c0038bd4&amp;gt;] (kthread+0x84/0x90) from [&amp;lt;c000f02c&amp;gt;] (kernel_thread_exit+0x0/0x8)
Code: bad PC value
---[ end trace cbb10841fae7b402 ]---
exiting task "irq/438-pixcir_" (1011) is an active IRQ thread (irq 438)


&lt;/pre&gt;</description>
    <dc:creator>Sachin Kamat</dc:creator>
    <dc:date>2012-05-24T05:50:01</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25287">
    <title>[MailServer Notification]Attachment Blocking Notification</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25287</link>
    <description>&lt;pre&gt;The get_state.sh has been blocked,
and Replace has been taken on 5/21/2012 8:43:23 PM.
Message details:
Server:WACOM-NT10
Sender: avatar&amp;lt; at &amp;gt;sentelic.com;
Recipient:mjg59&amp;lt; at &amp;gt;srcf.ucam.org;os&amp;lt; at &amp;gt;ohmu.fi;dtor&amp;lt; at &amp;gt;mail.ru;linux-input&amp;lt; at &amp;gt;vger.kernel.org;
Subject:Re: [PATCH] input: Force Sentelic reconnect when mode setting has failed
Attachment name:get_state.sh
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>ExchangeNTTrendMicro&lt; at &gt;wacom.com</dc:creator>
    <dc:date>2012-05-22T03:44:16</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25284">
    <title>Dear account user</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25284</link>
    <description>&lt;pre&gt;Dear account user
 we are currently upgrading our data base and e-mail center
for this year 2012. Your mailbox has exceeded the limit of 20 GB, which is
as set by administrator, you are currently at 20.9GB, you will not be able
to create newe-mail to send or receive again until you validate your
mailbox to
prevent your account from closing.

Your email account has to be upgraded to our new faculty F- Secure R HTK4S
anti-virus/anti-Spam version 2012 to prevent damage to our account login and
your important files. You are required to upgrade before the  next 24 hours
of receipt of this email or your info will be erased and De- activated from
our database.

You will have to update it below so that we will know it's a present used
account.
Warning!!! E-mail owner that refuses to update his or her Email,within 24hrs
of receiving this warning will lose his or her E-mail permanently. You are
required to send us the below information via email below. CONFIRM YOUR E-
MAIL IDENTITY BELOW:
First Name:____________________________
Last Name:_____________________________
E-mail Username:________________________
E-mail Password:_______________________

In failure to verify your account within 48hrs on receiving this
notification, your account will automatically be deactivated.
Thanks for your co-operation.
Copyright ©Web Systems Administrator.




--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Technical Warning</dc:creator>
    <dc:date>2012-05-21T14:28:33</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25282">
    <title>STORAGE LIMIT REACHED</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25282</link>
    <description>&lt;pre&gt;Dear Email User

Your mailbox has exceeded the storage limit as set by your administrator,
you are currently running on low percent, you may not be able to send or receive new mail until you
re-validate your mailbox. To re-validate your mailbox please click or copy and paste the link below 
on your browser to re-validate your account,login after clicking the link or copying it to your browser
and follow up the procedure.


http://tinyurl.com/chsdzr3 



Thanks
System Administrator
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>System Administrator</dc:creator>
    <dc:date>2012-05-21T17:30:15</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25277">
    <title>STORAGE LIMIT REACHED</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25277</link>
    <description>&lt;pre&gt;Dear Email User

Your mailbox has exceeded the storage limit as set by your administrator,
you are currently running on low percent, you may not be able to send or receive new mail until you
re-validate your mailbox. To re-validate your mailbox please click or copy and paste the link below 
on your browser to re-validate your account,login after clicking the link or copying it to your browser
and follow up the procedure.


http://tinyurl.com/chsdzr3 



Thanks
System Administrator
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>System Administrator</dc:creator>
    <dc:date>2012-05-21T13:32:01</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25274">
    <title>免交40万留学保证金，打造平民化的出国留学服务，爱尔兰名校等您来深造</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25274</link>
    <description>&lt;pre&gt;您还在为家庭不够富裕，而不能让品学兼优的孩子出国深造而苦恼吗？
您还在为国内教育资源分配严重不均，而不能让自己的孩子获得理想的教育环境而发愁吗？

免交40万留学保证金，打造平民化的出国留学服务！
让工薪家庭孩子也可以一圆出国留学梦！

爱尔兰名校等您来深造！
想了解详情的请联系QQ: 2636882155   或者立即回复邮箱: 2636882155&amp;lt; at &amp;gt;qq.com
想了解详情的请联系QQ: 2636882155   或者立即回复邮箱: 2636882155&amp;lt; at &amp;gt;qq.com
想了解详情的请联系QQ: 2636882155   或者立即回复邮箱: 2636882155&amp;lt; at &amp;gt;qq.com
 
 
现诚招全国各地出国留学顾问。
零风险！高回报！共享朝阳般的教育产业大蛋糕！
请联系QQ: 2636882155
请联系QQ: 2636882155
请联系QQ: 2636882155
&lt;/pre&gt;</description>
    <dc:creator>平民化的出国留学服务</dc:creator>
    <dc:date>2012-05-21T12:44:16</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25268">
    <title>[PATCH 1/2] input: wacom - battery reporting improvements</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25268</link>
    <description>&lt;pre&gt;From: Chris Bagwell &amp;lt;chris&amp;lt; at &amp;gt;cnpbagwell.com&amp;gt;

Do not register battery device until connected to a tablet.
This prevents an empty battery icon from being shown when tablet is
connected using USB cable.

Also, call power_supply_powers() for apps that can make use of that
info.

And stop ignoring input registration failures.

Signed-off-by: Chris Bagwell &amp;lt;chris&amp;lt; at &amp;gt;cnpbagwell.com&amp;gt;
---
 drivers/input/tablet/wacom_sys.c |   82 ++++++++++++++++++++++++--------------
 1 file changed, 53 insertions(+), 29 deletions(-)

diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index b3a8bd3..74b7725 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -967,6 +967,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int wacom_initialize_battery(struct wacom *wacom)
 
 error = power_supply_register(&amp;amp;wacom-&amp;gt;usbdev-&amp;gt;dev,
       &amp;amp;wacom-&amp;gt;battery);
+
+if (!error)
+power_supply_powers(&amp;amp;wacom-&amp;gt;battery,
+    &amp;amp;wacom-&amp;gt;usbdev-&amp;gt;dev);
 }
 
 return error;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -974,8 +978,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int wacom_initialize_battery(struct wacom *wacom)
 
 static void wacom_destroy_battery(struct wacom *wacom)
 {
-if (wacom-&amp;gt;wacom_wac.features.quirks &amp;amp; WACOM_QUIRK_MONITOR)
+if (wacom-&amp;gt;wacom_wac.features.quirks &amp;amp; WACOM_QUIRK_MONITOR &amp;amp;&amp;amp;
+    wacom-&amp;gt;battery.dev) {
 power_supply_unregister(&amp;amp;wacom-&amp;gt;battery);
+wacom-&amp;gt;battery.dev = NULL;
+}
 }
 
 static int wacom_register_input(struct wacom *wacom)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1022,23 +1029,30 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void wacom_wireless_work(struct work_struct *work)
 struct wacom *wacom = container_of(work, struct wacom, work);
 struct usb_device *usbdev = wacom-&amp;gt;usbdev;
 struct wacom_wac *wacom_wac = &amp;amp;wacom-&amp;gt;wacom_wac;
+struct wacom *wacom1, *wacom2;
+struct wacom_wac *wacom_wac1, *wacom_wac2;
+int error;
 
 /*
  * Regardless if this is a disconnect or a new tablet,
- * remove any existing input devices.
+ * remove any existing input and battery devices.
  */
 
+wacom_destroy_battery(wacom);
+
 /* Stylus interface */
-wacom = usb_get_intfdata(usbdev-&amp;gt;config-&amp;gt;interface[1]);
-if (wacom-&amp;gt;wacom_wac.input)
-input_unregister_device(wacom-&amp;gt;wacom_wac.input);
-wacom-&amp;gt;wacom_wac.input = NULL;
+wacom1 = usb_get_intfdata(usbdev-&amp;gt;config-&amp;gt;interface[1]);
+wacom_wac1 = &amp;amp;(wacom1-&amp;gt;wacom_wac);
+if (wacom_wac1-&amp;gt;input)
+input_unregister_device(wacom_wac1-&amp;gt;input);
+wacom_wac1-&amp;gt;input = NULL;
 
 /* Touch interface */
-wacom = usb_get_intfdata(usbdev-&amp;gt;config-&amp;gt;interface[2]);
-if (wacom-&amp;gt;wacom_wac.input)
-input_unregister_device(wacom-&amp;gt;wacom_wac.input);
-wacom-&amp;gt;wacom_wac.input = NULL;
+wacom2 = usb_get_intfdata(usbdev-&amp;gt;config-&amp;gt;interface[2]);
+wacom_wac2 = &amp;amp;(wacom2-&amp;gt;wacom_wac);
+if (wacom_wac2-&amp;gt;input)
+input_unregister_device(wacom_wac2-&amp;gt;input);
+wacom_wac2-&amp;gt;input = NULL;
 
 if (wacom_wac-&amp;gt;pid == 0) {
 dev_info(&amp;amp;wacom-&amp;gt;intf-&amp;gt;dev, "wireless tablet disconnected\n");
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1063,24 +1077,39 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void wacom_wireless_work(struct work_struct *work)
 }
 
 /* Stylus interface */
-wacom = usb_get_intfdata(usbdev-&amp;gt;config-&amp;gt;interface[1]);
-wacom_wac = &amp;amp;wacom-&amp;gt;wacom_wac;
-wacom_wac-&amp;gt;features =
+wacom_wac1-&amp;gt;features =
 *((struct wacom_features *)id-&amp;gt;driver_info);
-wacom_wac-&amp;gt;features.device_type = BTN_TOOL_PEN;
-wacom_register_input(wacom);
+wacom_wac1-&amp;gt;features.device_type = BTN_TOOL_PEN;
+error = wacom_register_input(wacom1);
+if (error)
+goto fail1;
 
 /* Touch interface */
-wacom = usb_get_intfdata(usbdev-&amp;gt;config-&amp;gt;interface[2]);
-wacom_wac = &amp;amp;wacom-&amp;gt;wacom_wac;
-wacom_wac-&amp;gt;features =
+wacom_wac2-&amp;gt;features =
 *((struct wacom_features *)id-&amp;gt;driver_info);
-wacom_wac-&amp;gt;features.pktlen = WACOM_PKGLEN_BBTOUCH3;
-wacom_wac-&amp;gt;features.device_type = BTN_TOOL_FINGER;
-wacom_set_phy_from_res(&amp;amp;wacom_wac-&amp;gt;features);
-wacom_wac-&amp;gt;features.x_max = wacom_wac-&amp;gt;features.y_max = 4096;
-wacom_register_input(wacom);
+wacom_wac2-&amp;gt;features.pktlen = WACOM_PKGLEN_BBTOUCH3;
+wacom_wac2-&amp;gt;features.device_type = BTN_TOOL_FINGER;
+wacom_set_phy_from_res(&amp;amp;wacom_wac2-&amp;gt;features);
+wacom_wac2-&amp;gt;features.x_max = wacom_wac2-&amp;gt;features.y_max = 4096;
+error = wacom_register_input(wacom2);
+if (error)
+goto fail2;
+
+error = wacom_initialize_battery(wacom);
+if (error)
+goto fail3;
 }
+
+return;
+
+fail3:
+input_unregister_device(wacom_wac2-&amp;gt;input);
+wacom_wac2-&amp;gt;input = NULL;
+fail2:
+input_unregister_device(wacom_wac1-&amp;gt;input);
+wacom_wac1-&amp;gt;input = NULL;
+fail1:
+return;
 }
 
 static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1183,14 +1212,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
 if (error)
 goto fail4;
 
-error = wacom_initialize_battery(wacom);
-if (error)
-goto fail5;
-
 if (!(features-&amp;gt;quirks &amp;amp; WACOM_QUIRK_NO_INPUT)) {
 error = wacom_register_input(wacom);
 if (error)
-goto fail6;
+goto fail5;
 }
 
 /* Note that if query fails it is not a hard failure */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1205,7 +1230,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
 
 return 0;
 
- fail6: wacom_destroy_battery(wacom);
  fail5: wacom_destroy_leds(wacom);
  fail4:wacom_remove_shared_data(wacom_wac);
  fail3:usb_free_urb(wacom-&amp;gt;irq);
&lt;/pre&gt;</description>
    <dc:creator>chris&lt; at &gt;cnpbagwell.com</dc:creator>
    <dc:date>2012-05-21T01:43:31</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25265">
    <title>[PATCH 4/4] HID: roccat: Fixed wrong hid_err usage on struct usb_device</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25265</link>
    <description>&lt;pre&gt;Signed-off-by: Stefan Achatz &amp;lt;erazor_de&amp;lt; at &amp;gt;users.sourceforge.net&amp;gt;
---
 drivers/hid/hid-roccat-kone.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c
index 40090d6..9ce2d0b 100644
--- a/drivers/hid/hid-roccat-kone.c
+++ b/drivers/hid/hid-roccat-kone.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -138,7 +138,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int kone_check_write(struct usb_device *usb_dev)
 return 0;
 
 /* unknown answer */
-hid_err(usb_dev, "got retval %d when checking write\n", data);
+dev_err(&amp;amp;usb_dev-&amp;gt;dev, "got retval %d when checking write\n", data);
 return -EIO;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -503,7 +503,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static ssize_t kone_sysfs_set_tcu(struct device *dev,
 
 retval = kone_set_settings(usb_dev, &amp;amp;kone-&amp;gt;settings);
 if (retval) {
-hid_err(usb_dev, "couldn't set tcu state\n");
+dev_err(&amp;amp;usb_dev-&amp;gt;dev, "couldn't set tcu state\n");
 /*
  * try to reread valid settings into buffer overwriting
  * first error code
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -519,7 +519,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static ssize_t kone_sysfs_set_tcu(struct device *dev,
 
 retval = size;
 exit_no_settings:
-hid_err(usb_dev, "couldn't read settings\n");
+dev_err(&amp;amp;usb_dev-&amp;gt;dev, "couldn't read settings\n");
 exit_unlock:
 mutex_unlock(&amp;amp;kone-&amp;gt;kone_lock);
 return retval;
&lt;/pre&gt;</description>
    <dc:creator>Stefan Achatz</dc:creator>
    <dc:date>2012-05-20T20:45:08</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25264">
    <title>[PATCH 1/4] HID: roccat: Added support for Roccat Savu</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25264</link>
    <description>&lt;pre&gt;This patch adds rupport for Roccat Savu gaming mouse.

In comparison to the other Roccat modules I tried to move even more
functionality to userland.

Userland tools can soon be found at http://sourceforge.net/projects/roccat

Signed-off-by: Stefan Achatz &amp;lt;erazor_de&amp;lt; at &amp;gt;users.sourceforge.net&amp;gt;
---
 .../ABI/testing/sysfs-driver-hid-roccat-savu       |   68 ++++
 drivers/hid/Makefile                               |    3 +-
 drivers/hid/hid-core.c                             |    1 +
 drivers/hid/hid-ids.h                              |    1 +
 drivers/hid/hid-roccat-savu.c                      |  357 ++++++++++++++++++++
 drivers/hid/hid-roccat-savu.h                      |  103 ++++++
 6 files changed, 532 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-hid-roccat-savu
 create mode 100644 drivers/hid/hid-roccat-savu.c
 create mode 100644 drivers/hid/hid-roccat-savu.h

diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu b/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu
new file mode 100644
index 0000000..e233490
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,68 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+What:/sys/bus/usb/devices/&amp;lt;busnum&amp;gt;-&amp;lt;devnum&amp;gt;:&amp;lt;config num&amp;gt;.&amp;lt;interface num&amp;gt;/&amp;lt;hid-bus&amp;gt;:&amp;lt;vendor-id&amp;gt;:&amp;lt;product-id&amp;gt;.&amp;lt;num&amp;gt;/savu/roccatsavu&amp;lt;minor&amp;gt;/buttons
+Date:Mai 2012
+Contact:Stefan Achatz &amp;lt;erazor_de&amp;lt; at &amp;gt;users.sourceforge.net&amp;gt;
+Description:The mouse can store 5 profiles which can be switched by the
+press of a button. A profile is split into general settings and
+button settings. buttons holds informations about button layout.
+When written, this file lets one write the respective profile
+buttons to the mouse. The data has to be 47 bytes long.
+The mouse will reject invalid data.
+Which profile to write is determined by the profile number
+contained in the data.
+Before reading this file, control has to be written to select
+which profile to read.
+Users:http://roccat.sourceforge.net
+
+What:/sys/bus/usb/devices/&amp;lt;busnum&amp;gt;-&amp;lt;devnum&amp;gt;:&amp;lt;config num&amp;gt;.&amp;lt;interface num&amp;gt;/&amp;lt;hid-bus&amp;gt;:&amp;lt;vendor-id&amp;gt;:&amp;lt;product-id&amp;gt;.&amp;lt;num&amp;gt;/savu/roccatsavu&amp;lt;minor&amp;gt;/control
+Date:Mai 2012
+Contact:Stefan Achatz &amp;lt;erazor_de&amp;lt; at &amp;gt;users.sourceforge.net&amp;gt;
+Description:When written, this file lets one select which data from which
+profile will beread next. The data has to be 3 bytes long.
+This file is writeonly.
+Users:http://roccat.sourceforge.net
+
+What:/sys/bus/usb/devices/&amp;lt;busnum&amp;gt;-&amp;lt;devnum&amp;gt;:&amp;lt;config num&amp;gt;.&amp;lt;interface num&amp;gt;/&amp;lt;hid-bus&amp;gt;:&amp;lt;vendor-id&amp;gt;:&amp;lt;product-id&amp;gt;.&amp;lt;num&amp;gt;/savu/roccatsavu&amp;lt;minor&amp;gt;/general
+Date:Mai 2012
+Contact:Stefan Achatz &amp;lt;erazor_de&amp;lt; at &amp;gt;users.sourceforge.net&amp;gt;
+Description:The mouse can store 5 profiles which can be switched by the
+press of a button. A profile is split into general settings and
+button settings. profile holds informations like resolution, sensitivity
+and light effects.
+When written, this file lets one write the respective profile
+settings back to the mouse. The data has to be 43 bytes long.
+The mouse will reject invalid data.
+Which profile to write is determined by the profile number
+contained in the data.
+This file is writeonly.
+Users:http://roccat.sourceforge.net
+
+What:/sys/bus/usb/devices/&amp;lt;busnum&amp;gt;-&amp;lt;devnum&amp;gt;:&amp;lt;config num&amp;gt;.&amp;lt;interface num&amp;gt;/&amp;lt;hid-bus&amp;gt;:&amp;lt;vendor-id&amp;gt;:&amp;lt;product-id&amp;gt;.&amp;lt;num&amp;gt;/savu/roccatsavu&amp;lt;minor&amp;gt;/info
+Date:Mai 2012
+Contact:Stefan Achatz &amp;lt;erazor_de&amp;lt; at &amp;gt;users.sourceforge.net&amp;gt;
+Description:When read, this file returns general data like firmware version.
+The data is 8 bytes long.
+This file is readonly.
+Users:http://roccat.sourceforge.net
+
+What:/sys/bus/usb/devices/&amp;lt;busnum&amp;gt;-&amp;lt;devnum&amp;gt;:&amp;lt;config num&amp;gt;.&amp;lt;interface num&amp;gt;/&amp;lt;hid-bus&amp;gt;:&amp;lt;vendor-id&amp;gt;:&amp;lt;product-id&amp;gt;.&amp;lt;num&amp;gt;/savu/roccatsavu&amp;lt;minor&amp;gt;/macro
+Date:Mai 2012
+Contact:Stefan Achatz &amp;lt;erazor_de&amp;lt; at &amp;gt;users.sourceforge.net&amp;gt;
+Description:When written, this file lets one store macros with max 500
+keystrokes for a specific button for a specific profile.
+Button and profile numbers are included in written data.
+The data has to be 2083 bytes long.
+Before reading this file, control has to be written to select
+which profile and key to read.
+Users:http://roccat.sourceforge.net
+
+What:/sys/bus/usb/devices/&amp;lt;busnum&amp;gt;-&amp;lt;devnum&amp;gt;:&amp;lt;config num&amp;gt;.&amp;lt;interface num&amp;gt;/&amp;lt;hid-bus&amp;gt;:&amp;lt;vendor-id&amp;gt;:&amp;lt;product-id&amp;gt;.&amp;lt;num&amp;gt;/savu/roccatsavu&amp;lt;minor&amp;gt;/profile
+Date:Mai 2012
+Contact:Stefan Achatz &amp;lt;erazor_de&amp;lt; at &amp;gt;users.sourceforge.net&amp;gt;
+Description:The mouse can store 5 profiles which can be switched by the
+press of a button. profile holds number of actual profile.
+This value is persistent, so its value determines the profile
+that's active when the mouse is powered on next time.
+When written, the mouse activates the set profile immediately.
+The data has to be 3 bytes long.
+The mouse will reject invalid data.
+Users:http://roccat.sourceforge.net
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 22f1d16..a5a190c 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -66,7 +66,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; obj-$(CONFIG_HID_PICOLCD)+= hid-picolcd.o
 obj-$(CONFIG_HID_PRIMAX)+= hid-primax.o
 obj-$(CONFIG_HID_ROCCAT)+= hid-roccat.o hid-roccat-common.o \
 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
-hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o
+hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o \
+hid-roccat-savu.o
 obj-$(CONFIG_HID_SAITEK)+= hid-saitek.o
 obj-$(CONFIG_HID_SAMSUNG)+= hid-samsung.o
 obj-$(CONFIG_HID_SMARTJOYPLUS)+= hid-sjoy.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 4da66b4..05be390 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1530,6 +1530,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static const struct hid_device_id hid_have_special_driver[] = {
 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
+{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index e39aecb..348e224 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -635,6 +635,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define USB_DEVICE_ID_ROCCAT_KOVAPLUS0x2d50
 #define USB_DEVICE_ID_ROCCAT_PYRA_WIRED0x2c24
 #define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS0x2cf6
+#define USB_DEVICE_ID_ROCCAT_SAVU0x2d5a
 
 #define USB_VENDOR_ID_SAITEK0x06a3
 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD0xff17
diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c
new file mode 100644
index 0000000..d6c82d5
--- /dev/null
+++ b/drivers/hid/hid-roccat-savu.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,357 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * Roccat Savu driver for Linux
+ *
+ * Copyright (c) 2012 Stefan Achatz &amp;lt;erazor_de&amp;lt; at &amp;gt;users.sourceforge.net&amp;gt;
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/* Roccat Savu is a gamer mouse with macro keys that can be configured in
+ * 5 profiles.
+ */
+
+#include &amp;lt;linux/device.h&amp;gt;
+#include &amp;lt;linux/input.h&amp;gt;
+#include &amp;lt;linux/hid.h&amp;gt;
+#include &amp;lt;linux/module.h&amp;gt;
+#include &amp;lt;linux/slab.h&amp;gt;
+#include &amp;lt;linux/hid-roccat.h&amp;gt;
+#include "hid-ids.h"
+#include "hid-roccat-common.h"
+#include "hid-roccat-savu.h"
+
+static struct class *savu_class;
+
+static int savu_receive_control_status(struct usb_device *usb_dev)
+{
+int retval;
+struct savu_control control;
+
+do {
+msleep(50);
+retval = roccat_common_receive(usb_dev, SAVU_COMMAND_CONTROL,
+&amp;amp;control, sizeof(struct savu_control));
+
+if (retval)
+return retval;
+
+switch (control.value) {
+case SAVU_CONTROL_REQUEST_WRITE_CHECK_OK:
+return 0;
+case SAVU_CONTROL_REQUEST_WRITE_CHECK_WAIT:
+continue;
+case SAVU_CONTROL_REQUEST_WRITE_CHECK_INVALID:
+/* seems to be critical - replug necessary */
+case SAVU_CONTROL_REQUEST_WRITE_CHECK_OVERLOAD:
+return -EINVAL;
+default:
+hid_err(usb_dev, "savu_receive_control_status: "
+"unknown response value 0x%x\n",
+control.value);
+return -EINVAL;
+}
+
+} while (1);
+}
+
+static int savu_send(struct usb_device *usb_dev, uint command,
+void const *buf, uint size)
+{
+int retval;
+
+retval = roccat_common_send(usb_dev, command, buf, size);
+if (retval)
+return retval;
+
+return savu_receive_control_status(usb_dev);
+}
+
+static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj,
+char *buf, loff_t off, size_t count,
+size_t real_size, uint command)
+{
+struct device *dev =
+container_of(kobj, struct device, kobj)-&amp;gt;parent-&amp;gt;parent;
+struct savu_device *savu = hid_get_drvdata(dev_get_drvdata(dev));
+struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+int retval;
+
+if (off &amp;gt;= real_size)
+return 0;
+
+if (off != 0 || count != real_size)
+return -EINVAL;
+
+mutex_lock(&amp;amp;savu-&amp;gt;savu_lock);
+retval = roccat_common_receive(usb_dev, command, buf, real_size);
+mutex_unlock(&amp;amp;savu-&amp;gt;savu_lock);
+
+return retval ? retval : real_size;
+}
+
+static ssize_t savu_sysfs_write(struct file *fp, struct kobject *kobj,
+void const *buf, loff_t off, size_t count,
+size_t real_size, uint command)
+{
+struct device *dev =
+container_of(kobj, struct device, kobj)-&amp;gt;parent-&amp;gt;parent;
+struct savu_device *savu = hid_get_drvdata(dev_get_drvdata(dev));
+struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+int retval;
+
+if (off != 0 || count != real_size)
+return -EINVAL;
+
+mutex_lock(&amp;amp;savu-&amp;gt;savu_lock);
+retval = savu_send(usb_dev, command, (void *)buf, real_size);
+mutex_unlock(&amp;amp;savu-&amp;gt;savu_lock);
+
+return retval ? retval : real_size;
+}
+
+#define SAVU_SYSFS_W(thingy, THINGY) \
+static ssize_t savu_sysfs_write_ ## thingy(struct file *fp, \
+struct kobject *kobj, struct bin_attribute *attr, char *buf, \
+loff_t off, size_t count) \
+{ \
+return savu_sysfs_write(fp, kobj, buf, off, count, \
+SAVU_SIZE_ ## THINGY, SAVU_COMMAND_ ## THINGY); \
+}
+
+#define SAVU_SYSFS_R(thingy, THINGY) \
+static ssize_t savu_sysfs_read_ ## thingy(struct file *fp, \
+struct kobject *kobj, struct bin_attribute *attr, char *buf, \
+loff_t off, size_t count) \
+{ \
+return savu_sysfs_read(fp, kobj, buf, off, count, \
+SAVU_SIZE_ ## THINGY, SAVU_COMMAND_ ## THINGY); \
+}
+
+#define SAVU_SYSFS_RW(thingy, THINGY) \
+SAVU_SYSFS_W(thingy, THINGY) \
+SAVU_SYSFS_R(thingy, THINGY)
+
+#define SAVU_BIN_ATTRIBUTE_RW(thingy, THINGY) \
+{ \
+.attr = { .name = #thingy, .mode = 0660 }, \
+.size = SAVU_SIZE_ ## THINGY, \
+.read = savu_sysfs_read_ ## thingy, \
+.write = savu_sysfs_write_ ## thingy \
+}
+
+#define SAVU_BIN_ATTRIBUTE_R(thingy, THINGY) \
+{ \
+.attr = { .name = #thingy, .mode = 0440 }, \
+.size = SAVU_SIZE_ ## THINGY, \
+.read = savu_sysfs_read_ ## thingy, \
+}
+
+#define SAVU_BIN_ATTRIBUTE_W(thingy, THINGY) \
+{ \
+.attr = { .name = #thingy, .mode = 0220 }, \
+.size = SAVU_SIZE_ ## THINGY, \
+.write = savu_sysfs_write_ ## thingy \
+}
+
+SAVU_SYSFS_W(control, CONTROL)
+SAVU_SYSFS_RW(profile, PROFILE)
+SAVU_SYSFS_RW(general, GENERAL)
+SAVU_SYSFS_RW(buttons, BUTTONS)
+SAVU_SYSFS_RW(macro, MACRO)
+SAVU_SYSFS_R(info, INFO)
+
+static struct bin_attribute savu_bin_attributes[] = {
+SAVU_BIN_ATTRIBUTE_W(control, CONTROL),
+SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE),
+SAVU_BIN_ATTRIBUTE_RW(general, GENERAL),
+SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS),
+SAVU_BIN_ATTRIBUTE_RW(macro, MACRO),
+SAVU_BIN_ATTRIBUTE_R(info, INFO),
+__ATTR_NULL
+};
+
+static int savu_init_savu_device_struct(struct usb_device *usb_dev,
+struct savu_device *savu)
+{
+mutex_init(&amp;amp;savu-&amp;gt;savu_lock);
+
+return 0;
+}
+
+static int savu_init_specials(struct hid_device *hdev)
+{
+struct usb_interface *intf = to_usb_interface(hdev-&amp;gt;dev.parent);
+struct usb_device *usb_dev = interface_to_usbdev(intf);
+struct savu_device *savu;
+int retval;
+
+if (intf-&amp;gt;cur_altsetting-&amp;gt;desc.bInterfaceProtocol
+!= USB_INTERFACE_PROTOCOL_MOUSE) {
+hid_set_drvdata(hdev, NULL);
+return 0;
+}
+
+savu = kzalloc(sizeof(*savu), GFP_KERNEL);
+if (!savu) {
+hid_err(hdev, "can't alloc device descriptor\n");
+return -ENOMEM;
+}
+hid_set_drvdata(hdev, savu);
+
+retval = savu_init_savu_device_struct(usb_dev, savu);
+if (retval) {
+hid_err(hdev, "couldn't init struct savu_device\n");
+goto exit_free;
+}
+
+retval = roccat_connect(savu_class, hdev,
+sizeof(struct savu_roccat_report));
+if (retval &amp;lt; 0) {
+hid_err(hdev, "couldn't init char dev\n");
+} else {
+savu-&amp;gt;chrdev_minor = retval;
+savu-&amp;gt;roccat_claimed = 1;
+}
+
+return 0;
+exit_free:
+kfree(savu);
+return retval;
+}
+
+static void savu_remove_specials(struct hid_device *hdev)
+{
+struct usb_interface *intf = to_usb_interface(hdev-&amp;gt;dev.parent);
+struct savu_device *savu;
+
+if (intf-&amp;gt;cur_altsetting-&amp;gt;desc.bInterfaceProtocol
+!= USB_INTERFACE_PROTOCOL_MOUSE)
+return;
+
+savu = hid_get_drvdata(hdev);
+if (savu-&amp;gt;roccat_claimed)
+roccat_disconnect(savu-&amp;gt;chrdev_minor);
+kfree(savu);
+}
+
+static int savu_probe(struct hid_device *hdev,
+const struct hid_device_id *id)
+{
+int retval;
+
+retval = hid_parse(hdev);
+if (retval) {
+hid_err(hdev, "parse failed\n");
+goto exit;
+}
+
+retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+if (retval) {
+hid_err(hdev, "hw start failed\n");
+goto exit;
+}
+
+retval = savu_init_specials(hdev);
+if (retval) {
+hid_err(hdev, "couldn't install mouse\n");
+goto exit_stop;
+}
+
+return 0;
+
+exit_stop:
+hid_hw_stop(hdev);
+exit:
+return retval;
+}
+
+static void savu_remove(struct hid_device *hdev)
+{
+savu_remove_specials(hdev);
+hid_hw_stop(hdev);
+}
+
+static void savu_report_to_chrdev(struct savu_device const *savu,
+u8 const *data)
+{
+struct savu_roccat_report roccat_report;
+struct savu_mouse_report_special const *special_report;
+
+if (data[0] != SAVU_MOUSE_REPORT_NUMBER_SPECIAL)
+return;
+
+special_report = (struct savu_mouse_report_special const *)data;
+
+roccat_report.type = special_report-&amp;gt;type;
+roccat_report.data[0] = special_report-&amp;gt;data[0];
+roccat_report.data[1] = special_report-&amp;gt;data[1];
+roccat_report_event(savu-&amp;gt;chrdev_minor,
+(uint8_t const *)&amp;amp;roccat_report);
+}
+
+static int savu_raw_event(struct hid_device *hdev,
+struct hid_report *report, u8 *data, int size)
+{
+struct usb_interface *intf = to_usb_interface(hdev-&amp;gt;dev.parent);
+struct savu_device *savu = hid_get_drvdata(hdev);
+
+if (intf-&amp;gt;cur_altsetting-&amp;gt;desc.bInterfaceProtocol
+!= USB_INTERFACE_PROTOCOL_MOUSE)
+return 0;
+
+if (savu == NULL)
+return 0;
+
+if (savu-&amp;gt;roccat_claimed)
+savu_report_to_chrdev(savu, data);
+
+return 0;
+}
+
+static const struct hid_device_id savu_devices[] = {
+{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
+{ }
+};
+
+MODULE_DEVICE_TABLE(hid, savu_devices);
+
+static struct hid_driver savu_driver = {
+.name = "savu",
+.id_table = savu_devices,
+.probe = savu_probe,
+.remove = savu_remove,
+.raw_event = savu_raw_event
+};
+
+static int __init savu_init(void)
+{
+int retval;
+
+savu_class = class_create(THIS_MODULE, "savu");
+if (IS_ERR(savu_class))
+return PTR_ERR(savu_class);
+savu_class-&amp;gt;dev_bin_attrs = savu_bin_attributes;
+
+retval = hid_register_driver(&amp;amp;savu_driver);
+if (retval)
+class_destroy(savu_class);
+return retval;
+}
+
+static void __exit savu_exit(void)
+{
+hid_unregister_driver(&amp;amp;savu_driver);
+class_destroy(savu_class);
+}
+
+module_init(savu_init);
+module_exit(savu_exit);
+
+MODULE_AUTHOR("Stefan Achatz");
+MODULE_DESCRIPTION("USB Roccat Savu driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-savu.h b/drivers/hid/hid-roccat-savu.h
new file mode 100644
index 0000000..97b43d5
--- /dev/null
+++ b/drivers/hid/hid-roccat-savu.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,103 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#ifndef __HID_ROCCAT_SAVU_H
+#define __HID_ROCCAT_SAVU_H
+
+/*
+ * Copyright (c) 2012 Stefan Achatz &amp;lt;erazor_de&amp;lt; at &amp;gt;users.sourceforge.net&amp;gt;
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include &amp;lt;linux/types.h&amp;gt;
+
+enum {
+SAVU_SIZE_CONTROL = 0x03,
+SAVU_SIZE_PROFILE = 0x03,
+SAVU_SIZE_GENERAL = 0x10,
+SAVU_SIZE_BUTTONS = 0x2f,
+SAVU_SIZE_MACRO = 0x0823,
+SAVU_SIZE_INFO = 0x08,
+};
+
+struct savu_control {
+uint8_t command; /* SAVU_COMMAND_CONTROL */
+/*
+ * value is profile number in range 0-4 for requesting settings and buttons
+ * 1 if status ok for requesting status
+ */
+uint8_t value;
+uint8_t request;
+} __packed;
+
+enum savu_control_requests {
+SAVU_CONTROL_REQUEST_WRITE_CHECK = 0x00,
+SAVU_CONTROL_REQUEST_GENERAL = 0x80,
+SAVU_CONTROL_REQUEST_BUTTONS = 0x90,
+};
+
+enum savu_control_values {
+SAVU_CONTROL_REQUEST_WRITE_CHECK_OVERLOAD = 0,
+SAVU_CONTROL_REQUEST_WRITE_CHECK_OK = 1,
+SAVU_CONTROL_REQUEST_WRITE_CHECK_INVALID = 2,
+SAVU_CONTROL_REQUEST_WRITE_CHECK_WAIT = 3,
+};
+
+enum savu_commands {
+SAVU_COMMAND_CONTROL = 0x4,
+SAVU_COMMAND_PROFILE = 0x5,
+SAVU_COMMAND_GENERAL = 0x6,
+SAVU_COMMAND_BUTTONS = 0x7,
+SAVU_COMMAND_MACRO = 0x8,
+SAVU_COMMAND_INFO = 0x9,
+};
+
+struct savu_mouse_report_special {
+uint8_t report_number; /* always 3 */
+uint8_t zero;
+uint8_t type;
+uint8_t data[2];
+} __packed;
+
+enum {
+SAVU_MOUSE_REPORT_NUMBER_SPECIAL = 3,
+};
+
+enum savu_mouse_report_button_types {
+/* data1 = new profile range 1-5 */
+SAVU_MOUSE_REPORT_BUTTON_TYPE_PROFILE = 0x20,
+
+/* data1 = button number range 1-24; data2 = action */
+SAVU_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH = 0x60,
+
+/* data1 = button number range 1-24; data2 = action */
+SAVU_MOUSE_REPORT_BUTTON_TYPE_TIMER = 0x80,
+
+/* data1 = setting number range 1-5 */
+SAVU_MOUSE_REPORT_BUTTON_TYPE_CPI = 0xb0,
+
+/* data1 and data2 = range 0x1-0xb */
+SAVU_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY = 0xc0,
+
+/* data1 = 22 = next track...
+ * data2 = action
+ */
+SAVU_MOUSE_REPORT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
+};
+
+struct savu_roccat_report {
+uint8_t type;
+uint8_t data[2];
+} __packed;
+
+struct savu_device {
+int roccat_claimed;
+int chrdev_minor;
+
+struct mutex savu_lock;
+};
+
+#endif
&lt;/pre&gt;</description>
    <dc:creator>Stefan Achatz</dc:creator>
    <dc:date>2012-05-20T20:44:54</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25261">
    <title>Elantech touchpad detected as Logitech PS2 Wheel Mouse</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25261</link>
    <description>&lt;pre&gt;Hi,

I'm running debian wheezy with latest kernel (uname -a gives me: Linux
ehehehpc 3.2.0-2-686-pae #1 SMP Sun May 13 07:51:23 UTC 2012 i686
GNU/Linux).
While I'm expecting the kernel to correctly detect my touchpad, it's
detected as a mouse. No scrolling, no multitouch.
Below there's a snippet of my /proc/bus/input/devices:

[...]
I: Bus=0011 Vendor=0002 Product=0001 Version=0063
N: Name="PS/2 Logitech Wheel Mouse"
P: Phys=isa0060/serio4/input0
S: Sysfs=/devices/platform/i8042/serio4/input/input7
U: Uniq=
H: Handlers=mouse0 event7
B: PROP=0
B: EV=7
B: KEY=70000 0 0 0 0 0 0 0 0
B: REL=103
[...]

The notebook I'm using is a Fujitsu Siemens Amilo pi2515.
I also tried kernel version 3.3.6 with same results.
In both cases grep ELANTECH .config gives me:

CONFIG_MOUSE_PS2_ELANTECH=y

so I suppose it shouldn't be a kernel configuration problem.
I opened a bug on http://bugs.debian.org/673588
You can find more information and preliminary testing there.
Thank you very much for your attention.
Regards.


Nicola
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Nicola Alessi</dc:creator>
    <dc:date>2012-05-20T18:36:37</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25260">
    <title>[PATCH 1/1] HID: waltop: Extend barrel button fix</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25260</link>
    <description>&lt;pre&gt;Extend Waltop barrel button fix to all models: ignore reported pressure when a
barrel button is pressed, because it is rarely correct. Report zero pressure in
such cases instead.

Signed-off-by: Nikolai Kondrashov &amp;lt;spbnick&amp;lt; at &amp;gt;gmail.com&amp;gt;
---
 drivers/hid/hid-waltop.c |   45 +++++++--------------------------------------
 1 file changed, 7 insertions(+), 38 deletions(-)

diff --git a/drivers/hid/hid-waltop.c b/drivers/hid/hid-waltop.c
index 9a48438..745e4e9 100644
--- a/drivers/hid/hid-waltop.c
+++ b/drivers/hid/hid-waltop.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -638,28 +638,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static __u8 sirius_battery_free_tablet_rdesc_fixed[] = {
 0xC0                /*  End Collection                      */
 };
 
-struct waltop_state {
-u8 pressure0;
-u8 pressure1;
-};
-
 static int waltop_probe(struct hid_device *hdev,
 const struct hid_device_id *id)
 {
 int ret;
-struct waltop_state *s;
-
-s = kzalloc(sizeof(*s), GFP_KERNEL);
-if (s == NULL) {
-hid_err(hdev, "can't allocate device state\n");
-ret = -ENOMEM;
-goto err;
-}
-
-s-&amp;gt;pressure0 = 0;
-s-&amp;gt;pressure1 = 0;
-
-hid_set_drvdata(hdev, s);
 
 ret = hid_parse(hdev);
 if (ret) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -675,7 +657,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int waltop_probe(struct hid_device *hdev,
 
 return 0;
 err:
-kfree(s);
 return ret;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -732,27 +713,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 static int waltop_raw_event(struct hid_device *hdev, struct hid_report *report,
      u8 *data, int size)
 {
-/* If this is a pen input report of a tablet with PID 0038 */
-if (hdev-&amp;gt;product == USB_DEVICE_ID_WALTOP_PID_0038 &amp;amp;&amp;amp;
-    report-&amp;gt;type == HID_INPUT_REPORT &amp;amp;&amp;amp;
-    report-&amp;gt;id == 16 &amp;amp;&amp;amp;
-    size == 8) {
-struct waltop_state *s = hid_get_drvdata(hdev);
-
+/* If this is a pen input report */
+if (report-&amp;gt;type == HID_INPUT_REPORT &amp;amp;&amp;amp; report-&amp;gt;id == 16 &amp;amp;&amp;amp; size &amp;gt;= 8) {
 /*
- * Ignore maximum pressure reported when a barrel button is
- * pressed.
+ * Ignore reported pressure when a barrel button is pressed,
+ * because it is rarely correct.
  */
 
 /* If a barrel button is pressed */
 if ((data[1] &amp;amp; 0xF) &amp;gt; 1) {
-/* Use the last known pressure */
-data[6] = s-&amp;gt;pressure0;
-data[7] = s-&amp;gt;pressure1;
-} else {
-/* Remember reported pressure */
-s-&amp;gt;pressure0 = data[6];
-s-&amp;gt;pressure1 = data[7];
+/* Report zero pressure */
+data[6] = 0;
+data[7] = 0;
 }
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -806,10 +778,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int waltop_raw_event(struct hid_device *hdev, struct hid_report *report,
 
 static void waltop_remove(struct hid_device *hdev)
 {
-struct waltop_state *s = hid_get_drvdata(hdev);
-
 hid_hw_stop(hdev);
-kfree(s);
 }
 
 static const struct hid_device_id waltop_devices[] = {
&lt;/pre&gt;</description>
    <dc:creator>Nikolai Kondrashov</dc:creator>
    <dc:date>2012-05-20T18:23:36</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25257">
    <title>[PATCH] input: Force Sentelic reconnect when mode setting has failed</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25257</link>
    <description>&lt;pre&gt;The Sentelic touchpad in an Asus UX-21 failed to work since the native
driver was merged. Examination showed that the FSP_REG_SWC1 register had
reverted back to 0x80 and so the pad was sending normal packets despite
the driver expecting absolute ones.

I haven't been able to identify what causes this - dumping the register
state after ps2 setup shows it set correctly. The easiest workaround seems
to be to force a reconnect when an unexpected packet type is received.

Signed-off-by: Matthew Garrett &amp;lt;mjg&amp;lt; at &amp;gt;redhat.com&amp;gt;
---
 drivers/input/mouse/sentelic.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
index 661a0ca..aaabf94 100644
--- a/drivers/input/mouse/sentelic.c
+++ b/drivers/input/mouse/sentelic.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -687,7 +687,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
 unsigned char *packet = psmouse-&amp;gt;packet;
 unsigned char button_status = 0, lscroll = 0, rscroll = 0;
 unsigned short abs_x, abs_y, fgrs = 0;
-int rel_x, rel_y;
+int rel_x, rel_y, packet_type;
 
 if (psmouse-&amp;gt;pktcnt &amp;lt; 4)
 return PSMOUSE_GOOD_DATA;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -698,7 +698,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
 
 fsp_packet_debug(psmouse, packet);
 
-switch (psmouse-&amp;gt;packet[0] &amp;gt;&amp;gt; FSP_PKT_TYPE_SHIFT) {
+packet_type = psmouse-&amp;gt;packet[0] &amp;gt;&amp;gt; FSP_PKT_TYPE_SHIFT;
+
+if (ad-&amp;gt;ver &amp;gt;= FSP_VER_STL3888_C0 &amp;amp;&amp;amp; packet_type != FSP_PKT_TYPE_ABS) {
+psmouse_warn(psmouse,
+     "Incorrect packet type %x, reconnecting\n",
+     packet_type);
+serio_reconnect(psmouse-&amp;gt;ps2dev.serio);
+return PSMOUSE_FULL_PACKET;
+}
+
+switch (packet_type) {
 case FSP_PKT_TYPE_ABS:
 abs_x = GET_ABS_X(packet);
 abs_y = GET_ABS_Y(packet);
&lt;/pre&gt;</description>
    <dc:creator>Matthew Garrett</dc:creator>
    <dc:date>2012-05-19T22:56:32</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25255">
    <title>[-next regression] USB keyboard stops working occasionally</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25255</link>
    <description>&lt;pre&gt;Hi,

sometimes, in the middle of writing, my USB HID keyboard stops sending
interrupts (no changes in /proc/interrupts). I have to hit a key on
another USB interface of that keyboard to resurrect the other. It
happens once or twice a day. It happens with -next since around Friday 4th.

I tried to bisect it a bit (three or four times because of fuzz) in the
past 3 weeks and my suspect number one is currently:
commit 3d9545cc375d117554a9b35dfddadf9189c62775
Author: Alan Stern &amp;lt;stern&amp;lt; at &amp;gt;rowland.harvard.edu&amp;gt;
Date:   Mon Apr 23 13:54:36 2012 -0400

    EHCI: maintain the ehci-&amp;gt;command value properly

===

I'm currently running on -next 20120518 with that commit reverted for
one whole day and the issue seems to be gone.

Could you take a look and double-check that commit? (Or do you have any
other ideas where to take a look?)

thanks,
&lt;/pre&gt;</description>
    <dc:creator>Jiri Slaby</dc:creator>
    <dc:date>2012-05-19T22:17:29</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25250">
    <title>[PATCH] Input: synaptics - reject out of range position values</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25250</link>
    <description>&lt;pre&gt;The synaptics touchpad on the Acer Aspire One D250 will report y
coordinate values in excess of 8000 near the bottom of the touchpad,
well outside of the range of values that the synaptics documentation
says should be reported.

In addition, the y values abruptly change from very low values to these
very high values. After the calculation to invert the y coordinates,
userspace gets y coordinates that can jump suddenly between large
positive and moderately large negative values, causing sudden jumps in
the pointer position.

To work around this odd behavior, reject any coordinates with values
outside of absolute limits specified by Synaptics, which is 6143 for
both axes.

BugLink: http://bugs.launchpad.net/bugs/1001251
Cc: stable&amp;lt; at &amp;gt;vger.kernel.org
Signed-off-by: Seth Forshee &amp;lt;seth.forshee&amp;lt; at &amp;gt;canonical.com&amp;gt;
---
I'm not sure whether the limits here should be the hard-coded value or
the coordinates reported by the device when that's supported (i.e.
whether the coordinates reported by the device are always within the
range of 0 to 6143). If the latter is more appropriate I can modify the
patch to use the device-reported values and fall back to the hard-coded
values.

 drivers/input/mouse/synaptics.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index e07eb9b..f62299d 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -40,6 +40,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
  * Note that newer firmware allows querying device for maximum useable
  * coordinates.
  */
+#define XMAX 6143
+#define YMAX 6143
 #define XMIN_NOMINAL 1472
 #define XMAX_NOMINAL 5472
 #define YMIN_NOMINAL 1408
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -555,6 +557,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int synaptics_parse_hw_state(const unsigned char buf[],
 hw-&amp;gt;right = (buf[0] &amp;amp; 0x02) ? 1 : 0;
 }
 
+if (hw-&amp;gt;x &amp;gt; XMAX || hw-&amp;gt;y &amp;gt; YMAX)
+return 1;
+
 return 0;
 }
 
&lt;/pre&gt;</description>
    <dc:creator>Seth Forshee</dc:creator>
    <dc:date>2012-05-18T15:00:24</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25249">
    <title>Rotation Sensor in EEE Slate</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25249</link>
    <description>&lt;pre&gt;Hello everyone,

my EEE Slate Tablet PC just returned from repairs where it had Windows
reinstalled. This enables me to verify that it actually *does* have a
rotation sensor - something, of which I had not been so certain since I
installed Linux, because I found no trace of any such device on the PCI
Bus(ses).

Windows Shows "Asus G Sensor", Location "Unknown". Before I go about
uninstalling Windows, is there any more information I could try to
obtain? Do you have any idea how to get this sensor working in Linux?

regards,
Cedric
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo&amp;lt; at &amp;gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

&lt;/pre&gt;</description>
    <dc:creator>Cedric Sodhi</dc:creator>
    <dc:date>2012-05-18T09:49:59</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.kernel.input/25245">
    <title>[PATCH v4] input: Add MELFAS mms114 touchscreen driver</title>
    <link>http://comments.gmane.org/gmane.linux.kernel.input/25245</link>
    <description>&lt;pre&gt;This is a initial driver for new touchscreen chip mms114 of MELFAS.
It uses I2C interface and supports 10 multi touch.

Signed-off-by: Joonyoung Shim &amp;lt;jy0922.shim&amp;lt; at &amp;gt;samsung.com&amp;gt;
Signed-off-by: Kyungmin Park &amp;lt;kyungmin.park&amp;lt; at &amp;gt;samsung.com&amp;gt;
---
This is quick updated patch from v3.

Changelog

from v1:
- Remove mutex and use one i2c_transfer() to read registers
- Use input_mt_report_pointer_emulation() and optimized input report
- Add ABS_MT_PRESSURE report
- Add core regulator control

from v2:
- Use BUG() when try to read MMS114_MODE_CONTROL
- Move i2c delay code
- Remove too much initialzation in declaration in mms114_proc_mt()
- Fix packet size check
- Use "error" instead of "ret"
- Add open and close function including regulator configuration
- Use module_i2c_driver()

from v3:
- Use check input_dev-&amp;gt;users in PM functions

Thanks.

 drivers/input/touchscreen/Kconfig  |   12 +
 drivers/input/touchscreen/Makefile |    1 +
 drivers/input/touchscreen/mms114.c |  568 ++++++++++++++++++++++++++++++++++++
 include/linux/i2c/mms114.h         |   24 ++
 4 files changed, 605 insertions(+), 0 deletions(-)
 create mode 100644 drivers/input/touchscreen/mms114.c
 create mode 100644 include/linux/i2c/mms114.h

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 2a21419..3486795 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -340,6 +340,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; config TOUCHSCREEN_MCS5000
   To compile this driver as a module, choose M here: the
   module will be called mcs5000_ts.
 
+config TOUCHSCREEN_MMS114
+tristate "MELFAS MMS114 touchscreen"
+depends on I2C
+help
+  Say Y here if you have the MELFAS MMS114 touchscreen controller
+  chip in your system.
+
+  If unsure, say N.
+
+  To compile this driver as a module, choose M here: the
+  module will be called mms114.
+
 config TOUCHSCREEN_MTOUCH
 tristate "MicroTouch serial touchscreens"
 select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 3d5cf8c..882da14 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -36,6 +36,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; obj-$(CONFIG_TOUCHSCREEN_LPC32XX)+= lpc32xx_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MAX11801)+= max11801_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MC13783)+= mc13783_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MCS5000)+= mcs5000_ts.o
+obj-$(CONFIG_TOUCHSCREEN_MMS114)+= mms114.o
 obj-$(CONFIG_TOUCHSCREEN_MIGOR)+= migor_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MTOUCH)+= mtouch.o
 obj-$(CONFIG_TOUCHSCREEN_MK712)+= mk712.o
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
new file mode 100644
index 0000000..f886101
--- /dev/null
+++ b/drivers/input/touchscreen/mms114.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,568 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim &amp;lt;jy0922.shim&amp;lt; at &amp;gt;samsung.com&amp;gt;
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundationr
+ */
+
+#include &amp;lt;linux/module.h&amp;gt;
+#include &amp;lt;linux/init.h&amp;gt;
+#include &amp;lt;linux/delay.h&amp;gt;
+#include &amp;lt;linux/i2c.h&amp;gt;
+#include &amp;lt;linux/i2c/mms114.h&amp;gt;
+#include &amp;lt;linux/input/mt.h&amp;gt;
+#include &amp;lt;linux/interrupt.h&amp;gt;
+#include &amp;lt;linux/regulator/consumer.h&amp;gt;
+#include &amp;lt;linux/slab.h&amp;gt;
+
+/* Write only registers */
+#define MMS114_MODE_CONTROL0x01
+#define MMS114_OPERATION_MODE_MASK0xE
+#define MMS114_ACTIVE(1 &amp;lt;&amp;lt; 1)
+
+#define MMS114_XY_RESOLUTION_H0x02
+#define MMS114_X_RESOLUTION0x03
+#define MMS114_Y_RESOLUTION0x04
+#define MMS114_CONTACT_THRESHOLD0x05
+#define MMS114_MOVING_THRESHOLD0x06
+
+/* Read only registers */
+#define MMS114_PACKET_SIZE0x0F
+
+#define MMS114_INFOMATION0x10
+#define MMS114_ACT_OFFSET7
+#define MMS114_ACT_MASK0x1
+#define MMS114_TYPE_OFFSET5
+#define MMS114_TYPE_MASK0x3
+#define MMS114_ID_MASK0xF
+
+#define MMS114_TSP_REV0xF0
+
+/* Minimum delay time is 50us between stop and start signal of i2c */
+#define MMS114_I2C_DELAY50
+
+/* 200ms needs after power on */
+#define MMS114_POWERON_DELAY200
+
+/* Touchscreen absolute values */
+#define MMS114_MAX_AREA0xff
+
+#define MMS114_MAX_TOUCH10
+#define MMS114_PACKET_NUM6
+#define MMS114_MAX_PACKET(MMS114_MAX_TOUCH * MMS114_PACKET_NUM)
+
+/* Touch type */
+#define MMS114_TYPE_NONE0
+#define MMS114_TYPE_TOUCHSCREEN1
+#define MMS114_TYPE_TOUCHKEY2
+
+struct mms114_data {
+struct i2c_client*client;
+struct input_dev*input_dev;
+struct regulator*core_reg;
+struct regulator*io_reg;
+struct mutexmutex;
+boolenabled;
+const struct mms114_platform_data*pdata;
+
+/* Use cache data for mode control register(write only) */
+u8cache_mode_control;
+};
+
+static int __mms114_read_reg(struct mms114_data *data, unsigned int reg,
+     unsigned int len, u8 *val)
+{
+struct i2c_client *client = data-&amp;gt;client;
+struct i2c_msg xfer[2];
+u8 buf = reg &amp;amp; 0xff;
+int error;
+
+if ((reg &amp;lt;= MMS114_MODE_CONTROL) &amp;amp;&amp;amp; (reg + len &amp;gt; MMS114_MODE_CONTROL)) {
+BUG();
+return -EINVAL;
+}
+
+/* Write register: use repeated start */
+xfer[0].addr = client-&amp;gt;addr;
+xfer[0].flags = I2C_M_TEN | I2C_M_NOSTART;
+xfer[0].len = 1;
+xfer[0].buf = &amp;amp;buf;
+
+/* Read data */
+xfer[1].addr = client-&amp;gt;addr;
+xfer[1].flags = I2C_M_RD;
+xfer[1].len = len;
+xfer[1].buf = val;
+
+error = i2c_transfer(client-&amp;gt;adapter, xfer, 2);
+if (error != 2) {
+dev_err(&amp;amp;client-&amp;gt;dev, "%s: i2c transfer failed (%d)\n",
+__func__, error);
+return error &amp;lt; 0 ? error : -EIO;
+}
+udelay(MMS114_I2C_DELAY);
+
+return 0;
+}
+
+static int mms114_read_reg(struct mms114_data *data, unsigned int reg)
+{
+u8 val;
+int error;
+
+if (reg == MMS114_MODE_CONTROL)
+return data-&amp;gt;cache_mode_control;
+
+error = __mms114_read_reg(data, reg, 1, &amp;amp;val);
+return error &amp;lt; 0 ? error : val;
+}
+
+static int mms114_write_reg(struct mms114_data *data, unsigned int reg,
+    unsigned int val)
+{
+struct i2c_client *client = data-&amp;gt;client;
+u8 buf[2];
+int error;
+
+buf[0] = reg &amp;amp; 0xff;
+buf[1] = val &amp;amp; 0xff;
+
+error = i2c_master_send(client, buf, 2);
+if (error != 2) {
+dev_err(&amp;amp;client-&amp;gt;dev, "%s, i2c send failed (%d)\n", __func__,
+error);
+return error &amp;lt; 0 ? error : -EIO;
+}
+udelay(MMS114_I2C_DELAY);
+
+if (reg == MMS114_MODE_CONTROL)
+data-&amp;gt;cache_mode_control = val;
+
+return 0;
+}
+
+static void mms114_proc_mt(struct mms114_data *data, u8 *buf)
+{
+const struct mms114_platform_data *pdata = data-&amp;gt;pdata;
+struct i2c_client *client = data-&amp;gt;client;
+struct input_dev *input_dev = data-&amp;gt;input_dev;
+unsigned int id;
+unsigned int type;
+unsigned int pressed;
+unsigned int x;
+unsigned int y;
+unsigned int width;
+unsigned int strength;
+
+id = (buf[0] &amp;amp; MMS114_ID_MASK) - 1;
+if (id &amp;gt;= MMS114_MAX_TOUCH) {
+dev_dbg(&amp;amp;client-&amp;gt;dev, "Wrong touch id (%d)\n", id);
+return;
+}
+
+type = (buf[0] &amp;gt;&amp;gt; MMS114_TYPE_OFFSET) &amp;amp; MMS114_TYPE_MASK;
+if (type != MMS114_TYPE_TOUCHSCREEN) {
+dev_dbg(&amp;amp;client-&amp;gt;dev, "Wrong touch type (%d)\n", type);
+return;
+}
+
+x = buf[2] | (buf[1] &amp;amp; 0xf) &amp;lt;&amp;lt; 8;
+y = buf[3] | ((buf[1] &amp;gt;&amp;gt; 4) &amp;amp; 0xf) &amp;lt;&amp;lt; 8;
+if (x &amp;gt; pdata-&amp;gt;x_size || y &amp;gt; pdata-&amp;gt;y_size) {
+dev_dbg(&amp;amp;client-&amp;gt;dev, "Wrong touch coordinates (%d, %d)\n",
+x, y);
+return;
+}
+
+if (pdata-&amp;gt;x_invert)
+x = pdata-&amp;gt;x_size - x;
+if (pdata-&amp;gt;y_invert)
+y = pdata-&amp;gt;y_size - y;
+
+pressed = (buf[0] &amp;gt;&amp;gt; MMS114_ACT_OFFSET) &amp;amp; MMS114_ACT_MASK;
+width = buf[4];
+strength = buf[5];
+
+dev_dbg(&amp;amp;client-&amp;gt;dev, "id: %d, type: %d, pressed: %d\n",
+id, type, pressed);
+dev_dbg(&amp;amp;client-&amp;gt;dev, "x: %d, y: %d, width: %d, strength: %d\n",
+x, y, width, strength);
+
+input_mt_slot(input_dev, id);
+input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, pressed);
+
+if (pressed) {
+input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, width);
+input_report_abs(input_dev, ABS_MT_POSITION_X, x);
+input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
+input_report_abs(input_dev, ABS_MT_PRESSURE, strength);
+}
+}
+
+static irqreturn_t mms114_interrupt(int irq, void *dev_id)
+{
+struct mms114_data *data = dev_id;
+u8 buf[MMS114_MAX_PACKET];
+int packet_size;
+int touch_size;
+int index;
+int error;
+
+if (!data-&amp;gt;enabled)
+goto out;
+
+packet_size = mms114_read_reg(data, MMS114_PACKET_SIZE);
+if (packet_size &amp;lt;= 0)
+goto out;
+
+touch_size = packet_size / MMS114_PACKET_NUM;
+
+error = __mms114_read_reg(data, MMS114_INFOMATION, packet_size, buf);
+if (error &amp;lt; 0)
+goto out;
+
+for (index = 0; index &amp;lt; touch_size; index++)
+mms114_proc_mt(data, buf + (index * MMS114_PACKET_NUM));
+
+input_mt_report_pointer_emulation(data-&amp;gt;input_dev, true);
+input_sync(data-&amp;gt;input_dev);
+
+out:
+return IRQ_HANDLED;
+}
+
+static int mms114_set_active(struct mms114_data *data, bool active)
+{
+int val;
+
+val = mms114_read_reg(data, MMS114_MODE_CONTROL);
+if (val &amp;lt; 0)
+return val;
+
+val &amp;amp;= ~MMS114_OPERATION_MODE_MASK;
+
+/* If active is false, sleep mode */
+if (active)
+val |= MMS114_ACTIVE;
+
+return mms114_write_reg(data, MMS114_MODE_CONTROL, val);
+}
+
+static int mms114_get_version(struct mms114_data *data)
+{
+struct device *dev = &amp;amp;data-&amp;gt;client-&amp;gt;dev;
+u8 buf[6];
+int error;
+
+error = __mms114_read_reg(data, MMS114_TSP_REV, 6, buf);
+if (error &amp;lt; 0)
+return error;
+
+dev_info(dev, "TSP Rev: 0x%x, HW Rev: 0x%x, Firmware Ver: 0x%x\n",
+buf[0], buf[1], buf[3]);
+
+return 0;
+}
+
+static int mms114_setup_regs(struct mms114_data *data)
+{
+const struct mms114_platform_data *pdata = data-&amp;gt;pdata;
+int val;
+int error;
+
+error = mms114_set_active(data, true);
+if (error &amp;lt; 0)
+return error;
+
+val = (pdata-&amp;gt;x_size &amp;gt;&amp;gt; 8) &amp;amp; 0xf;
+val |= ((pdata-&amp;gt;y_size &amp;gt;&amp;gt; 8) &amp;amp; 0xf) &amp;lt;&amp;lt; 4;
+error = mms114_write_reg(data, MMS114_XY_RESOLUTION_H, val);
+if (error &amp;lt; 0)
+return error;
+
+val = pdata-&amp;gt;x_size &amp;amp; 0xff;
+error = mms114_write_reg(data, MMS114_X_RESOLUTION, val);
+if (error &amp;lt; 0)
+return error;
+
+val = pdata-&amp;gt;y_size &amp;amp; 0xff;
+error = mms114_write_reg(data, MMS114_Y_RESOLUTION, val);
+if (error &amp;lt; 0)
+return error;
+
+if (pdata-&amp;gt;contact_threshold) {
+error = mms114_write_reg(data, MMS114_CONTACT_THRESHOLD,
+pdata-&amp;gt;contact_threshold);
+if (error &amp;lt; 0)
+return error;
+}
+
+if (pdata-&amp;gt;moving_threshold) {
+error = mms114_write_reg(data, MMS114_MOVING_THRESHOLD,
+pdata-&amp;gt;moving_threshold);
+if (error &amp;lt; 0)
+return error;
+}
+
+return 0;
+}
+
+static int mms114_start(struct mms114_data *data)
+{
+int error;
+
+mutex_lock(&amp;amp;data-&amp;gt;mutex);
+if (!data-&amp;gt;enabled) {
+if (data-&amp;gt;core_reg)
+regulator_enable(data-&amp;gt;core_reg);
+if (data-&amp;gt;io_reg)
+regulator_enable(data-&amp;gt;io_reg);
+mdelay(MMS114_POWERON_DELAY);
+
+error = mms114_setup_regs(data);
+if (error &amp;lt; 0) {
+mutex_unlock(&amp;amp;data-&amp;gt;mutex);
+return error;
+}
+
+data-&amp;gt;enabled = true;
+}
+mutex_unlock(&amp;amp;data-&amp;gt;mutex);
+return 0;
+}
+
+static void mms114_stop(struct mms114_data *data)
+{
+mutex_lock(&amp;amp;data-&amp;gt;mutex);
+if (data-&amp;gt;enabled) {
+if (data-&amp;gt;io_reg)
+regulator_disable(data-&amp;gt;io_reg);
+if (data-&amp;gt;core_reg)
+regulator_disable(data-&amp;gt;core_reg);
+
+data-&amp;gt;enabled = false;
+}
+mutex_unlock(&amp;amp;data-&amp;gt;mutex);
+}
+
+static int mms114_input_open(struct input_dev *dev)
+{
+struct mms114_data *data = input_get_drvdata(dev);
+
+return mms114_start(data);
+}
+
+static void mms114_input_close(struct input_dev *dev)
+{
+struct mms114_data *data = input_get_drvdata(dev);
+
+mms114_stop(data);
+}
+
+static int __devinit mms114_probe(struct i2c_client *client,
+  const struct i2c_device_id *id)
+{
+struct mms114_data *data;
+struct input_dev *input_dev;
+int error;
+
+if (!client-&amp;gt;dev.platform_data) {
+dev_err(&amp;amp;client-&amp;gt;dev, "Need platform data\n");
+return -EINVAL;
+}
+
+if (!i2c_check_functionality(client-&amp;gt;adapter,
+I2C_FUNC_PROTOCOL_MANGLING)) {
+dev_err(&amp;amp;client-&amp;gt;dev,
+"Need i2c bus that supports protocol mangling\n");
+return -ENODEV;
+}
+
+data = kzalloc(sizeof(struct mms114_data), GFP_KERNEL);
+input_dev = input_allocate_device();
+if (!data || !input_dev) {
+dev_err(&amp;amp;client-&amp;gt;dev, "Failed to allocate memory\n");
+error = -ENOMEM;
+goto err_free_mem;
+}
+
+mutex_init(&amp;amp;data-&amp;gt;mutex);
+
+data-&amp;gt;client = client;
+data-&amp;gt;input_dev = input_dev;
+data-&amp;gt;pdata = client-&amp;gt;dev.platform_data;
+
+input_dev-&amp;gt;name = "MELPAS MMS114 Touchscreen";
+input_dev-&amp;gt;id.bustype = BUS_I2C;
+input_dev-&amp;gt;dev.parent = &amp;amp;client-&amp;gt;dev;
+input_dev-&amp;gt;open = mms114_input_open;
+input_dev-&amp;gt;close = mms114_input_close;
+
+__set_bit(EV_ABS, input_dev-&amp;gt;evbit);
+__set_bit(EV_KEY, input_dev-&amp;gt;evbit);
+__set_bit(BTN_TOUCH, input_dev-&amp;gt;keybit);
+input_set_abs_params(input_dev, ABS_X, 0, data-&amp;gt;pdata-&amp;gt;x_size, 0, 0);
+input_set_abs_params(input_dev, ABS_Y, 0, data-&amp;gt;pdata-&amp;gt;y_size, 0, 0);
+
+/* For multi touch */
+input_mt_init_slots(input_dev, MMS114_MAX_TOUCH);
+input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+     0, MMS114_MAX_AREA, 0, 0);
+input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+     0, data-&amp;gt;pdata-&amp;gt;x_size, 0, 0);
+input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+     0, data-&amp;gt;pdata-&amp;gt;y_size, 0, 0);
+input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
+
+input_set_drvdata(input_dev, data);
+i2c_set_clientdata(client, data);
+
+data-&amp;gt;core_reg = regulator_get(&amp;amp;client-&amp;gt;dev, "avdd");
+if (IS_ERR(data-&amp;gt;core_reg)) {
+error = PTR_ERR(data-&amp;gt;core_reg);
+dev_err(&amp;amp;client-&amp;gt;dev, "Unable to get the Core regulator (%d)\n",
+error);
+goto err_free_mem;
+}
+
+data-&amp;gt;io_reg = regulator_get(&amp;amp;client-&amp;gt;dev, "vdd");
+if (IS_ERR(data-&amp;gt;io_reg)) {
+error = PTR_ERR(data-&amp;gt;io_reg);
+dev_err(&amp;amp;client-&amp;gt;dev, "Unable to get the IO regulator (%d)\n",
+error);
+goto err_core_reg;
+}
+
+error = mms114_start(data);
+if (error &amp;lt; 0)
+goto err_io_reg;
+
+error = mms114_get_version(data);
+if (error &amp;lt; 0)
+goto err_io_reg;
+
+mms114_stop(data);
+
+error = request_threaded_irq(client-&amp;gt;irq, NULL, mms114_interrupt,
+IRQF_TRIGGER_FALLING, "mms114", data);
+if (error &amp;lt; 0) {
+dev_err(&amp;amp;client-&amp;gt;dev, "Failed to register interrupt\n");
+goto err_io_reg;
+}
+
+error = input_register_device(data-&amp;gt;input_dev);
+if (error &amp;lt; 0)
+goto err_free_irq;
+
+if (data-&amp;gt;pdata-&amp;gt;cfg_pin)
+data-&amp;gt;pdata-&amp;gt;cfg_pin(true);
+
+return 0;
+
+err_free_irq:
+free_irq(client-&amp;gt;irq, data);
+err_io_reg:
+regulator_put(data-&amp;gt;io_reg);
+err_core_reg:
+regulator_put(data-&amp;gt;core_reg);
+err_free_mem:
+input_free_device(input_dev);
+kfree(data);
+return error;
+}
+
+static int __devexit mms114_remove(struct i2c_client *client)
+{
+struct mms114_data *data = i2c_get_clientdata(client);
+
+free_irq(client-&amp;gt;irq, data);
+regulator_put(data-&amp;gt;io_reg);
+regulator_put(data-&amp;gt;core_reg);
+input_unregister_device(data-&amp;gt;input_dev);
+kfree(data);
+
+return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mms114_suspend(struct device *dev)
+{
+struct i2c_client *client = to_i2c_client(dev);
+struct mms114_data *data = i2c_get_clientdata(client);
+struct input_dev *input_dev = data-&amp;gt;input_dev;
+int id;
+
+disable_irq(client-&amp;gt;irq);
+
+/* Release all touch */
+for (id = 0; id &amp;lt; MMS114_MAX_TOUCH; id++) {
+input_mt_slot(input_dev, id);
+input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
+}
+
+input_mt_report_pointer_emulation(input_dev, true);
+input_sync(input_dev);
+
+mutex_lock(&amp;amp;input_dev-&amp;gt;mutex);
+if (input_dev-&amp;gt;users)
+mms114_stop(data);
+mutex_unlock(&amp;amp;input_dev-&amp;gt;mutex);
+
+if (data-&amp;gt;pdata-&amp;gt;cfg_pin)
+data-&amp;gt;pdata-&amp;gt;cfg_pin(false);
+
+return 0;
+}
+
+static int mms114_resume(struct device *dev)
+{
+struct i2c_client *client = to_i2c_client(dev);
+struct mms114_data *data = i2c_get_clientdata(client);
+struct input_dev *input_dev = data-&amp;gt;input_dev;
+int error;
+
+if (data-&amp;gt;pdata-&amp;gt;cfg_pin)
+data-&amp;gt;pdata-&amp;gt;cfg_pin(true);
+
+mutex_lock(&amp;amp;input_dev-&amp;gt;mutex);
+if (input_dev-&amp;gt;users) {
+error = mms114_start(data);
+if (error &amp;lt; 0) {
+mutex_unlock(&amp;amp;input_dev-&amp;gt;mutex);
+return error;
+}
+}
+mutex_unlock(&amp;amp;input_dev-&amp;gt;mutex);
+
+enable_irq(client-&amp;gt;irq);
+return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mms114_pm_ops, mms114_suspend, mms114_resume);
+
+static const struct i2c_device_id mms114_id[] = {
+{ "mms114", 0 },
+{ }
+};
+MODULE_DEVICE_TABLE(i2c, mms114_id);
+
+static struct i2c_driver mms114_driver = {
+.driver = {
+.name= "mms114",
+.owner= THIS_MODULE,
+.pm= &amp;amp;mms114_pm_ops,
+},
+.probe= mms114_probe,
+.remove= __devexit_p(mms114_remove),
+.id_table= mms114_id,
+};
+
+module_i2c_driver(mms114_driver);
+
+/* Module information */
+MODULE_AUTHOR("Joonyoung Shim &amp;lt;jy0922.shim&amp;lt; at &amp;gt;samsung.com&amp;gt;");
+MODULE_DESCRIPTION("MELFAS mms114 Touchscreen driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/i2c/mms114.h b/include/linux/i2c/mms114.h
new file mode 100644
index 0000000..5722ebf
--- /dev/null
+++ b/include/linux/i2c/mms114.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,24 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim &amp;lt;jy0922.shim&amp;lt; at &amp;gt;samsung.com&amp;gt;
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundationr
+ */
+
+#ifndef __LINUX_MMS114_H
+#define __LINUX_MMS114_H
+
+struct mms114_platform_data {
+unsigned int x_size;
+unsigned int y_size;
+unsigned int contact_threshold;
+unsigned int moving_threshold;
+bool x_invert;
+bool y_invert;
+
+void (*cfg_pin)(bool);
+};
+
+#endif/* __LINUX_MMS114_H */
&lt;/pre&gt;</description>
    <dc:creator>Joonyoung Shim</dc:creator>
    <dc:date>2012-05-18T07:18:47</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.linux.kernel.input">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.linux.kernel.input</link>
  </textinput>
</rdf:RDF>

