Commit 396e6e49 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (68 commits)
  Input: adp5589-keys - add support for the ADP5585 derivatives
  Input: imx_keypad - add pm suspend and resume support
  Input: force feedback - potential integer wrap in input_ff_create()
  Input: tsc2007 - make sure that X plate resistance is specified
  Input: serio_raw - fix memory leak when closing char device
  Input: serio_raw - kick clients when disconnecting port
  Input: serio_raw - explicitly mark disconnected ports as dead
  Input: serio_raw - fix coding style issues
  Input: serio_raw - use dev_*() for messages
  Input: serio_raw - use bool for boolean data
  Input: serio_raw - perform proper locking when adding clients to list
  Input: serio_raw - rename serio_raw_list to serio_raw_client
  Input: serio_raw - use kref instead of rolling out its own refcounting
  Input: psmouse - switch to using dev_*() for messages
  Input: wacom - correct max Y value on medium bamboos
  Input: wacom - add ABS_DISTANCE to Bamboo Pen reports
  Input: wacom - remove unneeded touch pressure initialization
  Input: lm8323 - wrap suspend and resume in CONFIG_PM_SLEEP
  Input: ad7879-i2c - wrap suspend and resume in CONFIG_PM_SLEEP
  Input: synaptics_i2c - wrap suspend and resume in CONFIG_PM_SLEEP
  ...
parents 18974369 6ad390a2
What: /sys/class/hidraw/hidraw*/device/speed
Date: April 2010
Kernel Version: 2.6.35
Contact: linux-bluetooth@vger.kernel.org
Description:
The /sys/class/hidraw/hidraw*/device/speed file controls
reporting speed of Wacom bluetooth tablet. Reading from
this file returns 1 if tablet reports in high speed mode
or 0 otherwise. Writing to this file one of these values
switches reporting speed.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/led
Date: August 2011
Contact: linux-input@vger.kernel.org
Description:
Attribute group for control of the status LEDs and the OLEDs.
This attribute group is only available for Intuos 4 M, L,
and XL (with LEDs and OLEDs) and Cintiq 21UX2 (LEDs only).
Therefore its presence implicitly signifies the presence of
said LEDs and OLEDs on the tablet device.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/status0_luminance
Date: August 2011
Contact: linux-input@vger.kernel.org
Description:
Writing to this file sets the status LED luminance (1..127)
when the stylus does not touch the tablet surface, and no
button is pressed on the stylus. This luminance level is
normally lower than the level when a button is pressed.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/status1_luminance
Date: August 2011
Contact: linux-input@vger.kernel.org
Description:
Writing to this file sets the status LED luminance (1..127)
when the stylus touches the tablet surface, or any button is
pressed on the stylus.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/status_led0_select
Date: August 2011
Contact: linux-input@vger.kernel.org
Description:
Writing to this file sets which one of the four (for Intuos 4)
or of the right four (for Cintiq 21UX2) status LEDs is active (0..3).
The other three LEDs on the same side are always inactive.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/status_led1_select
Date: September 2011
Contact: linux-input@vger.kernel.org
Description:
Writing to this file sets which one of the left four (for Cintiq 21UX2)
status LEDs is active (0..3). The other three LEDs on the left are always
inactive.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/buttons_luminance
Date: August 2011
Contact: linux-input@vger.kernel.org
Description:
Writing to this file sets the overall luminance level (0..15)
of all eight button OLED displays.
What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/button<n>_rawimg
Date: August 2011
Contact: linux-input@vger.kernel.org
Description:
When writing a 1024 byte raw image in Wacom Intuos 4
interleaving format to the file, the image shows up on Button N
of the device. The image is a 64x32 pixel 4-bit gray image. The
1024 byte binary is split up into 16x 64 byte chunks. Each 64
byte chunk encodes the image data for two consecutive lines on
the display. The low nibble of each byte contains the first
line, and the high nibble contains the second line.
What: /sys/class/hidraw/hidraw*/device/speed
Date: April 2010
Kernel Version: 2.6.35
Contact: linux-bluetooth@vger.kernel.org
Description:
The /sys/class/hidraw/hidraw*/device/speed file controls
reporting speed of wacom bluetooth tablet. Reading from
this file returns 1 if tablet reports in high speed mode
or 0 otherwise. Writing to this file one of these values
switches reporting speed.
...@@ -16,15 +16,28 @@ Contents ...@@ -16,15 +16,28 @@ Contents
1. Introduction 1. Introduction
2. Extra knobs 2. Extra knobs
3. Hardware version 1 3. Differentiating hardware versions
3.1 Registers 4. Hardware version 1
3.2 Native relative mode 4 byte packet format
3.3 Native absolute mode 4 byte packet format
4. Hardware version 2
4.1 Registers 4.1 Registers
4.2 Native absolute mode 6 byte packet format 4.2 Native relative mode 4 byte packet format
4.2.1 One finger touch 4.3 Native absolute mode 4 byte packet format
4.2.2 Two finger touch 5. Hardware version 2
5.1 Registers
5.2 Native absolute mode 6 byte packet format
5.2.1 Parity checking and packet re-synchronization
5.2.2 One/Three finger touch
5.2.3 Two finger touch
6. Hardware version 3
6.1 Registers
6.2 Native absolute mode 6 byte packet format
6.2.1 One/Three finger touch
6.2.2 Two finger touch
7. Hardware version 4
7.1 Registers
7.2 Native absolute mode 6 byte packet format
7.2.1 Status packet
7.2.2 Head packet
7.2.3 Motion packet
...@@ -375,7 +388,7 @@ For all the other ones, there are just a few constant bits: ...@@ -375,7 +388,7 @@ For all the other ones, there are just a few constant bits:
In case an error is detected, all the packets are shifted by one (and packet[0] is discarded). In case an error is detected, all the packets are shifted by one (and packet[0] is discarded).
5.2.1 One/Three finger touch 5.2.2 One/Three finger touch
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
byte 0: byte 0:
...@@ -384,19 +397,19 @@ byte 0: ...@@ -384,19 +397,19 @@ byte 0:
n1 n0 w3 w2 . . R L n1 n0 w3 w2 . . R L
L, R = 1 when Left, Right mouse button pressed L, R = 1 when Left, Right mouse button pressed
n1..n0 = numbers of fingers on touchpad n1..n0 = number of fingers on touchpad
byte 1: byte 1:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
p7 p6 p5 p4 . x10 x9 x8 p7 p6 p5 p4 x11 x10 x9 x8
byte 2: byte 2:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
x7 x6 x5 x4 x3 x2 x1 x0 x7 x6 x5 x4 x3 x2 x1 x0
x10..x0 = absolute x value (horizontal) x11..x0 = absolute x value (horizontal)
byte 3: byte 3:
...@@ -420,7 +433,7 @@ byte 3: ...@@ -420,7 +433,7 @@ byte 3:
byte 4: byte 4:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
p3 p1 p2 p0 . . y9 y8 p3 p1 p2 p0 y11 y10 y9 y8
p7..p0 = pressure (not EF113) p7..p0 = pressure (not EF113)
...@@ -429,10 +442,10 @@ byte 5: ...@@ -429,10 +442,10 @@ byte 5:
bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0
y7 y6 y5 y4 y3 y2 y1 y0 y7 y6 y5 y4 y3 y2 y1 y0
y9..y0 = absolute y value (vertical) y11..y0 = absolute y value (vertical)
4.2.2 Two finger touch 5.2.3 Two finger touch
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
Note that the two pairs of coordinates are not exactly the coordinates of the Note that the two pairs of coordinates are not exactly the coordinates of the
...@@ -446,7 +459,7 @@ byte 0: ...@@ -446,7 +459,7 @@ byte 0:
n1 n0 ay8 ax8 . . R L n1 n0 ay8 ax8 . . R L
L, R = 1 when Left, Right mouse button pressed L, R = 1 when Left, Right mouse button pressed
n1..n0 = numbers of fingers on touchpad n1..n0 = number of fingers on touchpad
byte 1: byte 1:
...@@ -480,3 +493,253 @@ byte 5: ...@@ -480,3 +493,253 @@ byte 5:
by7 by8 by5 by4 by3 by2 by1 by0 by7 by8 by5 by4 by3 by2 by1 by0
by8..by0 = upper-right finger absolute y value by8..by0 = upper-right finger absolute y value
/////////////////////////////////////////////////////////////////////////////
6. Hardware version 3
==================
6.1 Registers
~~~~~~~~~
* reg_10
bit 7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 A
A: 1 = enable absolute tracking
6.2 Native absolute mode 6 byte packet format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 and 3 finger touch shares the same 6-byte packet format, except that
3 finger touch only reports the position of the center of all three fingers.
Firmware would send 12 bytes of data for 2 finger touch.
Note on debounce:
In case the box has unstable power supply or other electricity issues, or
when number of finger changes, F/W would send "debounce packet" to inform
driver that the hardware is in debounce status.
The debouce packet has the following signature:
byte 0: 0xc4
byte 1: 0xff
byte 2: 0xff
byte 3: 0x02
byte 4: 0xff
byte 5: 0xff
When we encounter this kind of packet, we just ignore it.
6.2.1 One/Three finger touch
~~~~~~~~~~~~~~~~~~~~~~
byte 0:
bit 7 6 5 4 3 2 1 0
n1 n0 w3 w2 0 1 R L
L, R = 1 when Left, Right mouse button pressed
n1..n0 = number of fingers on touchpad
byte 1:
bit 7 6 5 4 3 2 1 0
p7 p6 p5 p4 x11 x10 x9 x8
byte 2:
bit 7 6 5 4 3 2 1 0
x7 x6 x5 x4 x3 x2 x1 x0
x11..x0 = absolute x value (horizontal)
byte 3:
bit 7 6 5 4 3 2 1 0
0 0 w1 w0 0 0 1 0
w3..w0 = width of the finger touch
byte 4:
bit 7 6 5 4 3 2 1 0
p3 p1 p2 p0 y11 y10 y9 y8
p7..p0 = pressure
byte 5:
bit 7 6 5 4 3 2 1 0
y7 y6 y5 y4 y3 y2 y1 y0
y11..y0 = absolute y value (vertical)
6.2.2 Two finger touch
~~~~~~~~~~~~~~~~
The packet format is exactly the same for two finger touch, except the hardware
sends two 6 byte packets. The first packet contains data for the first finger,
the second packet has data for the second finger. So for two finger touch a
total of 12 bytes are sent.
/////////////////////////////////////////////////////////////////////////////
7. Hardware version 4
==================
7.1 Registers
~~~~~~~~~
* reg_07
bit 7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 A
A: 1 = enable absolute tracking
7.2 Native absolute mode 6 byte packet format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
v4 hardware is a true multitouch touchpad, capable of tracking up to 5 fingers.
Unfortunately, due to PS/2's limited bandwidth, its packet format is rather
complex.
Whenever the numbers or identities of the fingers changes, the hardware sends a
status packet to indicate how many and which fingers is on touchpad, followed by
head packets or motion packets. A head packet contains data of finger id, finger
position (absolute x, y values), width, and pressure. A motion packet contains
two fingers' position delta.
For example, when status packet tells there are 2 fingers on touchpad, then we
can expect two following head packets. If the finger status doesn't change,
the following packets would be motion packets, only sending delta of finger
position, until we receive a status packet.
One exception is one finger touch. when a status packet tells us there is only
one finger, the hardware would just send head packets afterwards.
7.2.1 Status packet
~~~~~~~~~~~~~
byte 0:
bit 7 6 5 4 3 2 1 0
. . . . 0 1 R L
L, R = 1 when Left, Right mouse button pressed
byte 1:
bit 7 6 5 4 3 2 1 0
. . . ft4 ft3 ft2 ft1 ft0
ft4 ft3 ft2 ft1 ft0 ftn = 1 when finger n is on touchpad
byte 2: not used
byte 3:
bit 7 6 5 4 3 2 1 0
. . . 1 0 0 0 0
constant bits
byte 4:
bit 7 6 5 4 3 2 1 0
p . . . . . . .
p = 1 for palm
byte 5: not used
7.2.2 Head packet
~~~~~~~~~~~
byte 0:
bit 7 6 5 4 3 2 1 0
w3 w2 w1 w0 0 1 R L
L, R = 1 when Left, Right mouse button pressed
w3..w0 = finger width (spans how many trace lines)
byte 1:
bit 7 6 5 4 3 2 1 0
p7 p6 p5 p4 x11 x10 x9 x8
byte 2:
bit 7 6 5 4 3 2 1 0
x7 x6 x5 x4 x3 x2 x1 x0
x11..x0 = absolute x value (horizontal)
byte 3:
bit 7 6 5 4 3 2 1 0
id2 id1 id0 1 0 0 0 1
id2..id0 = finger id
byte 4:
bit 7 6 5 4 3 2 1 0
p3 p1 p2 p0 y11 y10 y9 y8
p7..p0 = pressure
byte 5:
bit 7 6 5 4 3 2 1 0
y7 y6 y5 y4 y3 y2 y1 y0
y11..y0 = absolute y value (vertical)
7.2.3 Motion packet
~~~~~~~~~~~~~
byte 0:
bit 7 6 5 4 3 2 1 0
id2 id1 id0 w 0 1 R L
L, R = 1 when Left, Right mouse button pressed
id2..id0 = finger id
w = 1 when delta overflows (> 127 or < -128), in this case
firmware sends us (delta x / 5) and (delta y / 5)
byte 1:
bit 7 6 5 4 3 2 1 0
x7 x6 x5 x4 x3 x2 x1 x0
x7..x0 = delta x (two's complement)
byte 2:
bit 7 6 5 4 3 2 1 0
y7 y6 y5 y4 y3 y2 y1 y0
y7..y0 = delta y (two's complement)
byte 3:
bit 7 6 5 4 3 2 1 0
id2 id1 id0 1 0 0 1 0
id2..id0 = finger id
byte 4:
bit 7 6 5 4 3 2 1 0
x7 x6 x5 x4 x3 x2 x1 x0
x7..x0 = delta x (two's complement)
byte 5:
bit 7 6 5 4 3 2 1 0
y7 y6 y5 y4 y3 y2 y1 y0
y7..y0 = delta y (two's complement)
byte 0 ~ 2 for one finger
byte 3 ~ 5 for another
...@@ -65,6 +65,20 @@ the full state of each initiated contact has to reside in the receiving ...@@ -65,6 +65,20 @@ the full state of each initiated contact has to reside in the receiving
end. Upon receiving an MT event, one simply updates the appropriate end. Upon receiving an MT event, one simply updates the appropriate
attribute of the current slot. attribute of the current slot.
Some devices identify and/or track more contacts than they can report to the
driver. A driver for such a device should associate one type B slot with each
contact that is reported by the hardware. Whenever the identity of the
contact associated with a slot changes, the driver should invalidate that
slot by changing its ABS_MT_TRACKING_ID. If the hardware signals that it is
tracking more contacts than it is currently reporting, the driver should use
a BTN_TOOL_*TAP event to inform userspace of the total number of contacts
being tracked by the hardware at that moment. The driver should do this by
explicitly sending the corresponding BTN_TOOL_*TAP event and setting
use_count to false when calling input_mt_report_pointer_emulation().
The driver should only advertise as many slots as the hardware can report.
Userspace can detect that a driver can report more total contacts than slots
by noting that the largest supported BTN_TOOL_*TAP event is larger than the
total number of type B slots reported in the absinfo for the ABS_MT_SLOT axis.
Protocol Example A Protocol Example A
------------------ ------------------
......
...@@ -309,9 +309,10 @@ EXPORT_SYMBOL_GPL(input_ff_event); ...@@ -309,9 +309,10 @@ EXPORT_SYMBOL_GPL(input_ff_event);
* Once ff device is created you need to setup its upload, erase, * Once ff device is created you need to setup its upload, erase,
* playback and other handlers before registering input device * playback and other handlers before registering input device
*/ */
int input_ff_create(struct input_dev *dev, int max_effects) int input_ff_create(struct input_dev *dev, unsigned int max_effects)
{ {
struct ff_device *ff; struct ff_device *ff;
size_t ff_dev_size;
int i; int i;
if (!max_effects) { if (!max_effects) {
...@@ -319,8 +320,12 @@ int input_ff_create(struct input_dev *dev, int max_effects) ...@@ -319,8 +320,12 @@ int input_ff_create(struct input_dev *dev, int max_effects)
return -EINVAL; return -EINVAL;
} }
ff = kzalloc(sizeof(struct ff_device) + ff_dev_size = sizeof(struct ff_device) +
max_effects * sizeof(struct file *), GFP_KERNEL); max_effects * sizeof(struct file *);
if (ff_dev_size < max_effects) /* overflow */
return -EINVAL;
ff = kzalloc(ff_dev_size, GFP_KERNEL);
if (!ff) if (!ff)
return -ENOMEM; return -ENOMEM;
......
...@@ -117,6 +117,7 @@ void input_mt_report_finger_count(struct input_dev *dev, int count) ...@@ -117,6 +117,7 @@ void input_mt_report_finger_count(struct input_dev *dev, int count)
input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2); input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2);
input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3); input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3);
input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4); input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4);
input_event(dev, EV_KEY, BTN_TOOL_QUINTTAP, count == 5);
} }
EXPORT_SYMBOL(input_mt_report_finger_count); EXPORT_SYMBOL(input_mt_report_finger_count);
......
...@@ -49,8 +49,10 @@ static int input_open_polled_device(struct input_dev *input) ...@@ -49,8 +49,10 @@ static int input_open_polled_device(struct input_dev *input)
dev->open(dev); dev->open(dev);
/* Only start polling if polling is enabled */ /* Only start polling if polling is enabled */
if (dev->poll_interval > 0) if (dev->poll_interval > 0) {
queue_delayed_work(system_freezable_wq, &dev->work, 0); dev->poll(dev);
input_polldev_queue_work(dev);
}
return 0; return 0;
} }
......
...@@ -33,10 +33,10 @@ config KEYBOARD_ADP5588 ...@@ -33,10 +33,10 @@ config KEYBOARD_ADP5588
module will be called adp5588-keys. module will be called adp5588-keys.
config KEYBOARD_ADP5589 config KEYBOARD_ADP5589
tristate "ADP5589 I2C QWERTY Keypad and IO Expander" tristate "ADP5585/ADP5589 I2C QWERTY Keypad and IO Expander"
depends on I2C depends on I2C
help help
Say Y here if you want to use a ADP5589 attached to your Say Y here if you want to use a ADP5585/ADP5589 attached to your
system I2C bus. system I2C bus.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
......
...@@ -550,7 +550,7 @@ static int __devinit adp5588_probe(struct i2c_client *client, ...@@ -550,7 +550,7 @@ static int __devinit adp5588_probe(struct i2c_client *client,
} }
error = request_irq(client->irq, adp5588_irq, error = request_irq(client->irq, adp5588_irq,
IRQF_TRIGGER_FALLING | IRQF_DISABLED, IRQF_TRIGGER_FALLING,
client->dev.driver->name, kpad); client->dev.driver->name, kpad);
if (error) { if (error) {
dev_err(&client->dev, "irq %d busy?\n", client->irq); dev_err(&client->dev, "irq %d busy?\n", client->irq);
......
This diff is collapsed.
...@@ -271,7 +271,7 @@ static int __init davinci_ks_probe(struct platform_device *pdev) ...@@ -271,7 +271,7 @@ static int __init davinci_ks_probe(struct platform_device *pdev)
} }
error = request_irq(davinci_ks->irq, davinci_ks_interrupt, error = request_irq(davinci_ks->irq, davinci_ks_interrupt,
IRQF_DISABLED, pdev->name, davinci_ks); 0, pdev->name, davinci_ks);
if (error < 0) { if (error < 0) {
dev_err(dev, "unable to register davinci key scan interrupt\n"); dev_err(dev, "unable to register davinci key scan interrupt\n");
goto fail5; goto fail5;
......
...@@ -323,7 +323,7 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) ...@@ -323,7 +323,7 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, keypad); platform_set_drvdata(pdev, keypad);
err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, err = request_irq(keypad->irq, ep93xx_keypad_irq_handler,
IRQF_DISABLED, pdev->name, keypad); 0, pdev->name, keypad);
if (err) if (err)
goto failed_free_dev; goto failed_free_dev;
......
...@@ -461,8 +461,7 @@ static int gpio_keys_get_devtree_pdata(struct device *dev, ...@@ -461,8 +461,7 @@ static int gpio_keys_get_devtree_pdata(struct device *dev,
struct device_node *node, *pp; struct device_node *node, *pp;
int i; int i;
struct gpio_keys_button *buttons; struct gpio_keys_button *buttons;
const u32 *reg; u32 reg;
int len;
node = dev->of_node; node = dev->of_node;
if (node == NULL) if (node == NULL)
...@@ -470,7 +469,7 @@ static int gpio_keys_get_devtree_pdata(struct device *dev, ...@@ -470,7 +469,7 @@ static int gpio_keys_get_devtree_pdata(struct device *dev,
memset(pdata, 0, sizeof *pdata); memset(pdata, 0, sizeof *pdata);
pdata->rep = !!of_get_property(node, "autorepeat", &len); pdata->rep = !!of_get_property(node, "autorepeat", NULL);
/* First count the subnodes */ /* First count the subnodes */
pdata->nbuttons = 0; pdata->nbuttons = 0;
...@@ -498,22 +497,25 @@ static int gpio_keys_get_devtree_pdata(struct device *dev, ...@@ -498,22 +497,25 @@ static int gpio_keys_get_devtree_pdata(struct device *dev,
buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags); buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags);
buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW; buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW;
reg = of_get_property(pp, "linux,code", &len); if (of_property_read_u32(pp, "linux,code", &reg)) {
if (!reg) {
dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio); dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio);
goto out_fail; goto out_fail;
} }
buttons[i].code = be32_to_cpup(reg); buttons[i].code = reg;
buttons[i].desc = of_get_property(pp, "label", &len); buttons[i].desc = of_get_property(pp, "label", NULL);
reg = of_get_property(pp, "linux,input-type", &len); if (of_property_read_u32(pp, "linux,input-type", &reg) == 0)
buttons[i].type = reg ? be32_to_cpup(reg) : EV_KEY; buttons[i].type = reg;
else
buttons[i].type = EV_KEY;
buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
reg = of_get_property(pp, "debounce-interval", &len); if (of_property_read_u32(pp, "debounce-interval", &reg) == 0)
buttons[i].debounce_interval = reg ? be32_to_cpup(reg) : 5; buttons[i].debounce_interval = reg;
else
buttons[i].debounce_interval = 5;
i++; i++;
} }
......
...@@ -510,7 +510,7 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev) ...@@ -510,7 +510,7 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev)
/* Ensure that the keypad will stay dormant until opened */ /* Ensure that the keypad will stay dormant until opened */
imx_keypad_inhibit(keypad); imx_keypad_inhibit(keypad);
error = request_irq(irq, imx_keypad_irq_handler, IRQF_DISABLED, error = request_irq(irq, imx_keypad_irq_handler, 0,
pdev->name, keypad); pdev->name, keypad);
if (error) { if (error) {
dev_err(&pdev->dev, "failed to request IRQ\n"); dev_err(&pdev->dev, "failed to request IRQ\n");
...@@ -567,10 +567,54 @@ static int __devexit imx_keypad_remove(struct platform_device *pdev) ...@@ -567,10 +567,54 @@ static int __devexit imx_keypad_remove(struct platform_device *pdev)
return 0; return 0;
} }
#ifdef CONFIG_PM_SLEEP
static int imx_kbd_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_keypad *kbd = platform_get_drvdata(pdev);
struct input_dev *input_dev = kbd->input_dev;
/* imx kbd can wake up system even clock is disabled */
mutex_lock(&input_dev->mutex);
if (input_dev->users)
clk_disable(kbd->clk);
mutex_unlock(&input_dev->mutex);
if (device_may_wakeup(&pdev->dev))
enable_irq_wake(kbd->irq);
return 0;
}
static int imx_kbd_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_keypad *kbd = platform_get_drvdata(pdev);
struct input_dev *input_dev = kbd->input_dev;
if (device_may_wakeup(&pdev->dev))
disable_irq_wake(kbd->irq);
mutex_lock(&input_dev->mutex);
if (input_dev->users)
clk_enable(kbd->clk);
mutex_unlock(&input_dev->mutex);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume);
static struct platform_driver imx_keypad_driver = { static struct platform_driver imx_keypad_driver = {
.driver = { .driver = {
.name = "imx-keypad", .name = "imx-keypad",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pm = &imx_kbd_pm_ops,
}, },
.probe = imx_keypad_probe, .probe = imx_keypad_probe,
.remove = __devexit_p(imx_keypad_remove), .remove = __devexit_p(imx_keypad_remove),
......
...@@ -129,7 +129,7 @@ static int __devinit jornada720_kbd_probe(struct platform_device *pdev) ...@@ -129,7 +129,7 @@ static int __devinit jornada720_kbd_probe(struct platform_device *pdev)
err = request_irq(IRQ_GPIO0, err = request_irq(IRQ_GPIO0,
jornada720_kbd_interrupt, jornada720_kbd_interrupt,
IRQF_DISABLED | IRQF_TRIGGER_FALLING, IRQF_TRIGGER_FALLING,
"jornadakbd", pdev); "jornadakbd", pdev);
if (err) { if (err) {
printk(KERN_INFO "jornadakbd720_kbd: Unable to grab IRQ\n"); printk(KERN_INFO "jornadakbd720_kbd: Unable to grab IRQ\n");
......
...@@ -788,7 +788,7 @@ static int __devexit lm8323_remove(struct i2c_client *client) ...@@ -788,7 +788,7 @@ static int __devexit lm8323_remove(struct i2c_client *client)
return 0; return 0;
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP
/* /*
* We don't need to explicitly suspend the chip, as it already switches off * We don't need to explicitly suspend the chip, as it already switches off
* when there's no activity. * when there's no activity.
......
...@@ -343,7 +343,6 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev, ...@@ -343,7 +343,6 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev,
for (i = 0; i < pdata->num_row_gpios; i++) { for (i = 0; i < pdata->num_row_gpios; i++) {
err = request_irq(gpio_to_irq(pdata->row_gpios[i]), err = request_irq(gpio_to_irq(pdata->row_gpios[i]),
matrix_keypad_interrupt, matrix_keypad_interrupt,
IRQF_DISABLED |
IRQF_TRIGGER_RISING | IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING, IRQF_TRIGGER_FALLING,
"matrix-keypad", keypad); "matrix-keypad", keypad);
......
...@@ -535,7 +535,7 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) ...@@ -535,7 +535,7 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
input_dev->evbit[0] |= BIT_MASK(EV_REL); input_dev->evbit[0] |= BIT_MASK(EV_REL);
} }
error = request_irq(irq, pxa27x_keypad_irq_handler, IRQF_DISABLED, error = request_irq(irq, pxa27x_keypad_irq_handler, 0,
pdev->name, keypad); pdev->name, keypad);
if (error) { if (error) {
dev_err(&pdev->dev, "failed to request IRQ\n"); dev_err(&pdev->dev, "failed to request IRQ\n");
......
...@@ -148,7 +148,7 @@ static int __devinit pxa930_rotary_probe(struct platform_device *pdev) ...@@ -148,7 +148,7 @@ static int __devinit pxa930_rotary_probe(struct platform_device *pdev)
r->input_dev = input_dev; r->input_dev = input_dev;
input_set_drvdata(input_dev, r); input_set_drvdata(input_dev, r);
err = request_irq(irq, rotary_irq, IRQF_DISABLED, err = request_irq(irq, rotary_irq, 0,
"enhanced rotary", r); "enhanced rotary", r);
if (err) { if (err) {
dev_err(&pdev->dev, "failed to request IRQ\n"); dev_err(&pdev->dev, "failed to request IRQ\n");
......
...@@ -90,7 +90,7 @@ struct tc_keypad { ...@@ -90,7 +90,7 @@ struct tc_keypad {
bool keypad_stopped; bool keypad_stopped;
}; };
static int __devinit tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad) static int tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad)
{ {
int ret; int ret;
struct tc3589x *tc3589x = keypad->tc3589x; struct tc3589x *tc3589x = keypad->tc3589x;
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#define KBC_ROW_CFG0_0 0x8 #define KBC_ROW_CFG0_0 0x8
#define KBC_COL_CFG0_0 0x18 #define KBC_COL_CFG0_0 0x18
#define KBC_TO_CNT_0 0x24
#define KBC_INIT_DLY_0 0x28 #define KBC_INIT_DLY_0 0x28
#define KBC_RPT_DLY_0 0x2c #define KBC_RPT_DLY_0 0x2c
#define KBC_KP_ENT0_0 0x30 #define KBC_KP_ENT0_0 0x30
...@@ -70,6 +71,7 @@ struct tegra_kbc { ...@@ -70,6 +71,7 @@ struct tegra_kbc {
spinlock_t lock; spinlock_t lock;
unsigned int repoll_dly; unsigned int repoll_dly;
unsigned long cp_dly_jiffies; unsigned long cp_dly_jiffies;
unsigned int cp_to_wkup_dly;
bool use_fn_map; bool use_fn_map;
bool use_ghost_filter; bool use_ghost_filter;
const struct tegra_kbc_platform_data *pdata; const struct tegra_kbc_platform_data *pdata;
...@@ -258,12 +260,10 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) ...@@ -258,12 +260,10 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc)
u32 val = 0; u32 val = 0;
unsigned int i; unsigned int i;
unsigned int num_down = 0; unsigned int num_down = 0;
unsigned long flags;
bool fn_keypress = false; bool fn_keypress = false;
bool key_in_same_row = false; bool key_in_same_row = false;
bool key_in_same_col = false; bool key_in_same_col = false;
spin_lock_irqsave(&kbc->lock, flags);
for (i = 0; i < KBC_MAX_KPENT; i++) { for (i = 0; i < KBC_MAX_KPENT; i++) {
if ((i % 4) == 0) if ((i % 4) == 0)
val = readl(kbc->mmio + KBC_KP_ENT0_0 + i); val = readl(kbc->mmio + KBC_KP_ENT0_0 + i);
...@@ -292,7 +292,7 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) ...@@ -292,7 +292,7 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc)
* any 2 of the 3 keys share a row, and any 2 of them share a column. * any 2 of the 3 keys share a row, and any 2 of them share a column.
* If so ignore the key presses for this iteration. * If so ignore the key presses for this iteration.
*/ */
if ((kbc->use_ghost_filter) && (num_down >= 3)) { if (kbc->use_ghost_filter && num_down >= 3) {
for (i = 0; i < num_down; i++) { for (i = 0; i < num_down; i++) {
unsigned int j; unsigned int j;
u8 curr_col = scancodes[i] & 0x07; u8 curr_col = scancodes[i] & 0x07;
...@@ -325,8 +325,6 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) ...@@ -325,8 +325,6 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc)
} }
} }
spin_unlock_irqrestore(&kbc->lock, flags);
/* Ignore the key presses for this iteration? */ /* Ignore the key presses for this iteration? */
if (key_in_same_col && key_in_same_row) if (key_in_same_col && key_in_same_row)
return; return;
...@@ -341,6 +339,18 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) ...@@ -341,6 +339,18 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc)
kbc->num_pressed_keys = num_down; kbc->num_pressed_keys = num_down;
} }
static void tegra_kbc_set_fifo_interrupt(struct tegra_kbc *kbc, bool enable)
{
u32 val;
val = readl(kbc->mmio + KBC_CONTROL_0);
if (enable)
val |= KBC_CONTROL_FIFO_CNT_INT_EN;
else
val &= ~KBC_CONTROL_FIFO_CNT_INT_EN;
writel(val, kbc->mmio + KBC_CONTROL_0);
}
static void tegra_kbc_keypress_timer(unsigned long data) static void tegra_kbc_keypress_timer(unsigned long data)
{ {
struct tegra_kbc *kbc = (struct tegra_kbc *)data; struct tegra_kbc *kbc = (struct tegra_kbc *)data;
...@@ -348,6 +358,8 @@ static void tegra_kbc_keypress_timer(unsigned long data) ...@@ -348,6 +358,8 @@ static void tegra_kbc_keypress_timer(unsigned long data)
u32 val; u32 val;
unsigned int i; unsigned int i;
spin_lock_irqsave(&kbc->lock, flags);
val = (readl(kbc->mmio + KBC_INT_0) >> 4) & 0xf; val = (readl(kbc->mmio + KBC_INT_0) >> 4) & 0xf;
if (val) { if (val) {
unsigned long dly; unsigned long dly;
...@@ -369,26 +381,19 @@ static void tegra_kbc_keypress_timer(unsigned long data) ...@@ -369,26 +381,19 @@ static void tegra_kbc_keypress_timer(unsigned long data)
kbc->num_pressed_keys = 0; kbc->num_pressed_keys = 0;
/* All keys are released so enable the keypress interrupt */ /* All keys are released so enable the keypress interrupt */
spin_lock_irqsave(&kbc->lock, flags); tegra_kbc_set_fifo_interrupt(kbc, true);
val = readl(kbc->mmio + KBC_CONTROL_0);
val |= KBC_CONTROL_FIFO_CNT_INT_EN;
writel(val, kbc->mmio + KBC_CONTROL_0);
spin_unlock_irqrestore(&kbc->lock, flags);
} }
spin_unlock_irqrestore(&kbc->lock, flags);
} }
static irqreturn_t tegra_kbc_isr(int irq, void *args) static irqreturn_t tegra_kbc_isr(int irq, void *args)
{ {
struct tegra_kbc *kbc = args; struct tegra_kbc *kbc = args;
u32 val, ctl; unsigned long flags;
u32 val;
/* spin_lock_irqsave(&kbc->lock, flags);
* Until all keys are released, defer further processing to
* the polling loop in tegra_kbc_keypress_timer
*/
ctl = readl(kbc->mmio + KBC_CONTROL_0);
ctl &= ~KBC_CONTROL_FIFO_CNT_INT_EN;
writel(ctl, kbc->mmio + KBC_CONTROL_0);
/* /*
* Quickly bail out & reenable interrupts if the fifo threshold * Quickly bail out & reenable interrupts if the fifo threshold
...@@ -399,15 +404,15 @@ static irqreturn_t tegra_kbc_isr(int irq, void *args) ...@@ -399,15 +404,15 @@ static irqreturn_t tegra_kbc_isr(int irq, void *args)
if (val & KBC_INT_FIFO_CNT_INT_STATUS) { if (val & KBC_INT_FIFO_CNT_INT_STATUS) {
/* /*
* Schedule timer to run when hardware is in continuous * Until all keys are released, defer further processing to
* polling mode. * the polling loop in tegra_kbc_keypress_timer.
*/ */
tegra_kbc_set_fifo_interrupt(kbc, false);
mod_timer(&kbc->timer, jiffies + kbc->cp_dly_jiffies); mod_timer(&kbc->timer, jiffies + kbc->cp_dly_jiffies);
} else {
ctl |= KBC_CONTROL_FIFO_CNT_INT_EN;
writel(ctl, kbc->mmio + KBC_CONTROL_0);
} }
spin_unlock_irqrestore(&kbc->lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -455,7 +460,6 @@ static void tegra_kbc_config_pins(struct tegra_kbc *kbc) ...@@ -455,7 +460,6 @@ static void tegra_kbc_config_pins(struct tegra_kbc *kbc)
static int tegra_kbc_start(struct tegra_kbc *kbc) static int tegra_kbc_start(struct tegra_kbc *kbc)
{ {
const struct tegra_kbc_platform_data *pdata = kbc->pdata; const struct tegra_kbc_platform_data *pdata = kbc->pdata;
unsigned long flags;
unsigned int debounce_cnt; unsigned int debounce_cnt;
u32 val = 0; u32 val = 0;
...@@ -493,7 +497,6 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) ...@@ -493,7 +497,6 @@ static int tegra_kbc_start(struct tegra_kbc *kbc)
* Atomically clear out any remaining entries in the key FIFO * Atomically clear out any remaining entries in the key FIFO
* and enable keyboard interrupts. * and enable keyboard interrupts.
*/ */
spin_lock_irqsave(&kbc->lock, flags);
while (1) { while (1) {
val = readl(kbc->mmio + KBC_INT_0); val = readl(kbc->mmio + KBC_INT_0);
val >>= 4; val >>= 4;
...@@ -504,7 +507,6 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) ...@@ -504,7 +507,6 @@ static int tegra_kbc_start(struct tegra_kbc *kbc)
val = readl(kbc->mmio + KBC_KP_ENT1_0); val = readl(kbc->mmio + KBC_KP_ENT1_0);
} }
writel(0x7, kbc->mmio + KBC_INT_0); writel(0x7, kbc->mmio + KBC_INT_0);
spin_unlock_irqrestore(&kbc->lock, flags);
enable_irq(kbc->irq); enable_irq(kbc->irq);
...@@ -734,18 +736,30 @@ static int tegra_kbc_suspend(struct device *dev) ...@@ -734,18 +736,30 @@ static int tegra_kbc_suspend(struct device *dev)
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct tegra_kbc *kbc = platform_get_drvdata(pdev); struct tegra_kbc *kbc = platform_get_drvdata(pdev);
mutex_lock(&kbc->idev->mutex);
if (device_may_wakeup(&pdev->dev)) { if (device_may_wakeup(&pdev->dev)) {
tegra_kbc_setup_wakekeys(kbc, true); disable_irq(kbc->irq);
enable_irq_wake(kbc->irq); del_timer_sync(&kbc->timer);
tegra_kbc_set_fifo_interrupt(kbc, false);
/* Forcefully clear the interrupt status */ /* Forcefully clear the interrupt status */
writel(0x7, kbc->mmio + KBC_INT_0); writel(0x7, kbc->mmio + KBC_INT_0);
/*
* Store the previous resident time of continuous polling mode.
* Force the keyboard into interrupt mode.
*/
kbc->cp_to_wkup_dly = readl(kbc->mmio + KBC_TO_CNT_0);
writel(0, kbc->mmio + KBC_TO_CNT_0);
tegra_kbc_setup_wakekeys(kbc, true);
msleep(30); msleep(30);
enable_irq_wake(kbc->irq);
} else { } else {
mutex_lock(&kbc->idev->mutex);
if (kbc->idev->users) if (kbc->idev->users)
tegra_kbc_stop(kbc); tegra_kbc_stop(kbc);
mutex_unlock(&kbc->idev->mutex);
} }
mutex_unlock(&kbc->idev->mutex);
return 0; return 0;
} }
...@@ -756,15 +770,22 @@ static int tegra_kbc_resume(struct device *dev) ...@@ -756,15 +770,22 @@ static int tegra_kbc_resume(struct device *dev)
struct tegra_kbc *kbc = platform_get_drvdata(pdev); struct tegra_kbc *kbc = platform_get_drvdata(pdev);
int err = 0; int err = 0;
mutex_lock(&kbc->idev->mutex);
if (device_may_wakeup(&pdev->dev)) { if (device_may_wakeup(&pdev->dev)) {
disable_irq_wake(kbc->irq); disable_irq_wake(kbc->irq);
tegra_kbc_setup_wakekeys(kbc, false); tegra_kbc_setup_wakekeys(kbc, false);
/* Restore the resident time of continuous polling mode. */
writel(kbc->cp_to_wkup_dly, kbc->mmio + KBC_TO_CNT_0);
tegra_kbc_set_fifo_interrupt(kbc, true);
enable_irq(kbc->irq);
} else { } else {
mutex_lock(&kbc->idev->mutex);
if (kbc->idev->users) if (kbc->idev->users)
err = tegra_kbc_start(kbc); err = tegra_kbc_start(kbc);
mutex_unlock(&kbc->idev->mutex);
} }
mutex_unlock(&kbc->idev->mutex);
return err; return err;
} }
......
...@@ -203,7 +203,7 @@ static int __devinit w90p910_keypad_probe(struct platform_device *pdev) ...@@ -203,7 +203,7 @@ static int __devinit w90p910_keypad_probe(struct platform_device *pdev)
input_dev->keycode, input_dev->keybit); input_dev->keycode, input_dev->keybit);
error = request_irq(keypad->irq, w90p910_keypad_irq_handler, error = request_irq(keypad->irq, w90p910_keypad_irq_handler,
IRQF_DISABLED, pdev->name, keypad); 0, pdev->name, keypad);
if (error) { if (error) {
dev_err(&pdev->dev, "failed to request IRQ\n"); dev_err(&pdev->dev, "failed to request IRQ\n");
goto failed_put_clk; goto failed_put_clk;
......
...@@ -62,6 +62,17 @@ config INPUT_AD714X_SPI ...@@ -62,6 +62,17 @@ config INPUT_AD714X_SPI
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called ad714x-spi. module will be called ad714x-spi.
config INPUT_BMA150
tristate "BMA150/SMB380 acceleration sensor support"
depends on I2C
select INPUT_POLLDEV
help
Say Y here if you have Bosch Sensortec's BMA150 or SMB380
acceleration sensor hooked to an I2C bus.
To compile this driver as a module, choose M here: the
module will be called bma150.
config INPUT_PCSPKR config INPUT_PCSPKR
tristate "PC Speaker support" tristate "PC Speaker support"
depends on PCSPKR_PLATFORM depends on PCSPKR_PLATFORM
...@@ -74,6 +85,29 @@ config INPUT_PCSPKR ...@@ -74,6 +85,29 @@ config INPUT_PCSPKR
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called pcspkr. module will be called pcspkr.
config INPUT_PM8XXX_VIBRATOR
tristate "Qualcomm PM8XXX vibrator support"
depends on MFD_PM8XXX
select INPUT_FF_MEMLESS
help
This option enables device driver support for the vibrator
on Qualcomm PM8xxx chip. This driver supports ff-memless interface
from input framework.
To compile this driver as module, choose M here: the
module will be called pm8xxx-vibrator.
config INPUT_PMIC8XXX_PWRKEY
tristate "PMIC8XXX power key support"
depends on MFD_PM8XXX
help
Say Y here if you want support for the PMIC8XXX power key.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called pmic8xxx-pwrkey.
config INPUT_SPARCSPKR config INPUT_SPARCSPKR
tristate "SPARC Speaker support" tristate "SPARC Speaker support"
depends on PCI && SPARC64 depends on PCI && SPARC64
...@@ -379,17 +413,6 @@ config INPUT_PWM_BEEPER ...@@ -379,17 +413,6 @@ config INPUT_PWM_BEEPER
To compile this driver as a module, choose M here: the module will be To compile this driver as a module, choose M here: the module will be
called pwm-beeper. called pwm-beeper.
config INPUT_PMIC8XXX_PWRKEY
tristate "PMIC8XXX power key support"
depends on MFD_PM8XXX
help
Say Y here if you want support for the PMIC8XXX power key.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called pmic8xxx-pwrkey.
config INPUT_GPIO_ROTARY_ENCODER config INPUT_GPIO_ROTARY_ENCODER
tristate "Rotary encoders connected to GPIO pins" tristate "Rotary encoders connected to GPIO pins"
depends on GPIOLIB && GENERIC_GPIO depends on GPIOLIB && GENERIC_GPIO
......
...@@ -17,6 +17,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o ...@@ -17,6 +17,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o
obj-$(CONFIG_INPUT_BMA150) += bma150.o
obj-$(CONFIG_INPUT_CM109) += cm109.o obj-$(CONFIG_INPUT_CM109) += cm109.o
obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o
obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o
...@@ -34,9 +35,10 @@ obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o ...@@ -34,9 +35,10 @@ obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o
obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o
obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_PM8XXX_VIBRATOR) += pm8xxx-vibrator.o
obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY) += pmic8xxx-pwrkey.o
obj-$(CONFIG_INPUT_POWERMATE) += powermate.o obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o
obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY) += pmic8xxx-pwrkey.o
obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o
obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
......
...@@ -116,13 +116,13 @@ static struct i2c_driver ad714x_i2c_driver = { ...@@ -116,13 +116,13 @@ static struct i2c_driver ad714x_i2c_driver = {
.id_table = ad714x_id, .id_table = ad714x_id,
}; };
static __init int ad714x_i2c_init(void) static int __init ad714x_i2c_init(void)
{ {
return i2c_add_driver(&ad714x_i2c_driver); return i2c_add_driver(&ad714x_i2c_driver);
} }
module_init(ad714x_i2c_init); module_init(ad714x_i2c_init);
static __exit void ad714x_i2c_exit(void) static void __exit ad714x_i2c_exit(void)
{ {
i2c_del_driver(&ad714x_i2c_driver); i2c_del_driver(&ad714x_i2c_driver);
} }
......
This diff is collapsed.
...@@ -111,7 +111,7 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev) ...@@ -111,7 +111,7 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev)
input_dev->event = ixp4xx_spkr_event; input_dev->event = ixp4xx_spkr_event;
err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt, err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt,
IRQF_DISABLED | IRQF_NO_SUSPEND, "ixp4xx-beeper", IRQF_NO_SUSPEND, "ixp4xx-beeper",
(void *) dev->id); (void *) dev->id);
if (err) if (err)
goto err_free_device; goto err_free_device;
......
...@@ -88,13 +88,13 @@ static int mma8450_write(struct mma8450 *m, unsigned off, u8 v) ...@@ -88,13 +88,13 @@ static int mma8450_write(struct mma8450 *m, unsigned off, u8 v)
return 0; return 0;
} }
static int mma8450_read_xyz(struct mma8450 *m, int *x, int *y, int *z) static int mma8450_read_block(struct mma8450 *m, unsigned off,
u8 *buf, size_t size)
{ {
struct i2c_client *c = m->client; struct i2c_client *c = m->client;
u8 buff[6];
int err; int err;
err = i2c_smbus_read_i2c_block_data(c, MMA8450_OUT_X_LSB, 6, buff); err = i2c_smbus_read_i2c_block_data(c, off, size, buf);
if (err < 0) { if (err < 0) {
dev_err(&c->dev, dev_err(&c->dev,
"failed to read block data at 0x%02x, error %d\n", "failed to read block data at 0x%02x, error %d\n",
...@@ -102,10 +102,6 @@ static int mma8450_read_xyz(struct mma8450 *m, int *x, int *y, int *z) ...@@ -102,10 +102,6 @@ static int mma8450_read_xyz(struct mma8450 *m, int *x, int *y, int *z)
return err; return err;
} }
*x = ((buff[1] << 4) & 0xff0) | (buff[0] & 0xf);
*y = ((buff[3] << 4) & 0xff0) | (buff[2] & 0xf);
*z = ((buff[5] << 4) & 0xff0) | (buff[4] & 0xf);
return 0; return 0;
} }
...@@ -114,7 +110,7 @@ static void mma8450_poll(struct input_polled_dev *dev) ...@@ -114,7 +110,7 @@ static void mma8450_poll(struct input_polled_dev *dev)
struct mma8450 *m = dev->private; struct mma8450 *m = dev->private;
int x, y, z; int x, y, z;
int ret; int ret;
int err; u8 buf[6];
ret = mma8450_read(m, MMA8450_STATUS); ret = mma8450_read(m, MMA8450_STATUS);
if (ret < 0) if (ret < 0)
...@@ -123,10 +119,14 @@ static void mma8450_poll(struct input_polled_dev *dev) ...@@ -123,10 +119,14 @@ static void mma8450_poll(struct input_polled_dev *dev)
if (!(ret & MMA8450_STATUS_ZXYDR)) if (!(ret & MMA8450_STATUS_ZXYDR))
return; return;
err = mma8450_read_xyz(m, &x, &y, &z); ret = mma8450_read_block(m, MMA8450_OUT_X_LSB, buf, sizeof(buf));
if (err) if (ret < 0)
return; return;
x = ((buf[1] << 4) & 0xff0) | (buf[0] & 0xf);
y = ((buf[3] << 4) & 0xff0) | (buf[2] & 0xf);
z = ((buf[5] << 4) & 0xff0) | (buf[4] & 0xf);
input_report_abs(dev->input, ABS_X, x); input_report_abs(dev->input, ABS_X, x);
input_report_abs(dev->input, ABS_Y, y); input_report_abs(dev->input, ABS_Y, y);
input_report_abs(dev->input, ABS_Z, z); input_report_abs(dev->input, ABS_Z, z);
......
/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/mfd/pm8xxx/core.h>
#define VIB_DRV 0x4A
#define VIB_DRV_SEL_MASK 0xf8
#define VIB_DRV_SEL_SHIFT 0x03
#define VIB_DRV_EN_MANUAL_MASK 0xfc
#define VIB_MAX_LEVEL_mV (3100)
#define VIB_MIN_LEVEL_mV (1200)
#define VIB_MAX_LEVELS (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV)
#define MAX_FF_SPEED 0xff
/**
* struct pm8xxx_vib - structure to hold vibrator data
* @vib_input_dev: input device supporting force feedback
* @work: work structure to set the vibration parameters
* @dev: device supporting force feedback
* @speed: speed of vibration set from userland
* @active: state of vibrator
* @level: level of vibration to set in the chip
* @reg_vib_drv: VIB_DRV register value
*/
struct pm8xxx_vib {
struct input_dev *vib_input_dev;
struct work_struct work;
struct device *dev;
int speed;
int level;
bool active;
u8 reg_vib_drv;
};
/**
* pm8xxx_vib_read_u8 - helper to read a byte from pmic chip
* @vib: pointer to vibrator structure
* @data: placeholder for data to be read
* @reg: register address
*/
static int pm8xxx_vib_read_u8(struct pm8xxx_vib *vib,
u8 *data, u16 reg)
{
int rc;
rc = pm8xxx_readb(vib->dev->parent, reg, data);
if (rc < 0)
dev_warn(vib->dev, "Error reading pm8xxx reg 0x%x(0x%x)\n",
reg, rc);
return rc;
}
/**
* pm8xxx_vib_write_u8 - helper to write a byte to pmic chip
* @vib: pointer to vibrator structure
* @data: data to write
* @reg: register address
*/
static int pm8xxx_vib_write_u8(struct pm8xxx_vib *vib,
u8 data, u16 reg)
{
int rc;
rc = pm8xxx_writeb(vib->dev->parent, reg, data);
if (rc < 0)
dev_warn(vib->dev, "Error writing pm8xxx reg 0x%x(0x%x)\n",
reg, rc);
return rc;
}
/**
* pm8xxx_vib_set - handler to start/stop vibration
* @vib: pointer to vibrator structure
* @on: state to set
*/
static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
{
int rc;
u8 val = vib->reg_vib_drv;
if (on)
val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
else
val &= ~VIB_DRV_SEL_MASK;
rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
if (rc < 0)
return rc;
vib->reg_vib_drv = val;
return 0;
}
/**
* pm8xxx_work_handler - worker to set vibration level
* @work: pointer to work_struct
*/
static void pm8xxx_work_handler(struct work_struct *work)
{
struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work);
int rc;
u8 val;
rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
if (rc < 0)
return;
/*
* pmic vibrator supports voltage ranges from 1.2 to 3.1V, so
* scale the level to fit into these ranges.
*/
if (vib->speed) {
vib->active = true;
vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) +
VIB_MIN_LEVEL_mV;
vib->level /= 100;
} else {
vib->active = false;
vib->level = VIB_MIN_LEVEL_mV / 100;
}
pm8xxx_vib_set(vib, vib->active);
}
/**
* pm8xxx_vib_close - callback of input close callback
* @dev: input device pointer
*
* Turns off the vibrator.
*/
static void pm8xxx_vib_close(struct input_dev *dev)
{
struct pm8xxx_vib *vib = input_get_drvdata(dev);
cancel_work_sync(&vib->work);
if (vib->active)
pm8xxx_vib_set(vib, false);
}
/**
* pm8xxx_vib_play_effect - function to handle vib effects.
* @dev: input device pointer
* @data: data of effect
* @effect: effect to play
*
* Currently this driver supports only rumble effects.
*/
static int pm8xxx_vib_play_effect(struct input_dev *dev, void *data,
struct ff_effect *effect)
{
struct pm8xxx_vib *vib = input_get_drvdata(dev);
vib->speed = effect->u.rumble.strong_magnitude >> 8;
if (!vib->speed)
vib->speed = effect->u.rumble.weak_magnitude >> 9;
schedule_work(&vib->work);
return 0;
}
static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)
{
struct pm8xxx_vib *vib;
struct input_dev *input_dev;
int error;
u8 val;
vib = kzalloc(sizeof(*vib), GFP_KERNEL);
input_dev = input_allocate_device();
if (!vib || !input_dev) {
dev_err(&pdev->dev, "couldn't allocate memory\n");
error = -ENOMEM;
goto err_free_mem;
}
INIT_WORK(&vib->work, pm8xxx_work_handler);
vib->dev = &pdev->dev;
vib->vib_input_dev = input_dev;
/* operate in manual mode */
error = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
if (error < 0)
goto err_free_mem;
val &= ~VIB_DRV_EN_MANUAL_MASK;
error = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
if (error < 0)
goto err_free_mem;
vib->reg_vib_drv = val;
input_dev->name = "pm8xxx_vib_ffmemless";
input_dev->id.version = 1;
input_dev->dev.parent = &pdev->dev;
input_dev->close = pm8xxx_vib_close;
input_set_drvdata(input_dev, vib);
input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE);
error = input_ff_create_memless(input_dev, NULL,
pm8xxx_vib_play_effect);
if (error) {
dev_err(&pdev->dev,
"couldn't register vibrator as FF device\n");
goto err_free_mem;
}
error = input_register_device(input_dev);
if (error) {
dev_err(&pdev->dev, "couldn't register input device\n");
goto err_destroy_memless;
}
platform_set_drvdata(pdev, vib);
return 0;
err_destroy_memless:
input_ff_destroy(input_dev);
err_free_mem:
input_free_device(input_dev);
kfree(vib);
return error;
}
static int __devexit pm8xxx_vib_remove(struct platform_device *pdev)
{
struct pm8xxx_vib *vib = platform_get_drvdata(pdev);
input_unregister_device(vib->vib_input_dev);
kfree(vib);
platform_set_drvdata(pdev, NULL);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int pm8xxx_vib_suspend(struct device *dev)
{
struct pm8xxx_vib *vib = dev_get_drvdata(dev);
/* Turn off the vibrator */
pm8xxx_vib_set(vib, false);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL);
static struct platform_driver pm8xxx_vib_driver = {
.probe = pm8xxx_vib_probe,
.remove = __devexit_p(pm8xxx_vib_remove),
.driver = {
.name = "pm8xxx-vib",
.owner = THIS_MODULE,
.pm = &pm8xxx_vib_pm_ops,
},
};
static int __init pm8xxx_vib_init(void)
{
return platform_driver_register(&pm8xxx_vib_driver);
}
module_init(pm8xxx_vib_init);
static void __exit pm8xxx_vib_exit(void)
{
platform_driver_unregister(&pm8xxx_vib_driver);
}
module_exit(pm8xxx_vib_exit);
MODULE_ALIAS("platform:pm8xxx_vib");
MODULE_DESCRIPTION("PMIC8xxx vibrator driver based on ff-memless framework");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Amy Maloche <amaloche@codeaurora.org>");
...@@ -228,7 +228,7 @@ static void twl6040_vibra_close(struct input_dev *input) ...@@ -228,7 +228,7 @@ static void twl6040_vibra_close(struct input_dev *input)
mutex_unlock(&info->mutex); mutex_unlock(&info->mutex);
} }
#if CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int twl6040_vibra_suspend(struct device *dev) static int twl6040_vibra_suspend(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
......
...@@ -23,13 +23,6 @@ ...@@ -23,13 +23,6 @@
#include "psmouse.h" #include "psmouse.h"
#include "alps.h" #include "alps.h"
#undef DEBUG
#ifdef DEBUG
#define dbg(format, arg...) printk(KERN_INFO "alps.c: " format "\n", ## arg)
#else
#define dbg(format, arg...) do {} while (0)
#endif
#define ALPS_OLDPROTO 0x01 /* old style input */ #define ALPS_OLDPROTO 0x01 /* old style input */
#define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */ #define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */
#define ALPS_PASS 0x04 /* device has a pass-through port */ #define ALPS_PASS 0x04 /* device has a pass-through port */
...@@ -297,10 +290,10 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) ...@@ -297,10 +290,10 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
psmouse->packet[4] | psmouse->packet[4] |
psmouse->packet[5]) & 0x80) || psmouse->packet[5]) & 0x80) ||
(!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) { (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) {
dbg("refusing packet %x %x %x %x " psmouse_dbg(psmouse,
"(suspected interleaved ps/2)\n", "refusing packet %x %x %x %x (suspected interleaved ps/2)\n",
psmouse->packet[3], psmouse->packet[4], psmouse->packet[3], psmouse->packet[4],
psmouse->packet[5], psmouse->packet[6]); psmouse->packet[5], psmouse->packet[6]);
return PSMOUSE_BAD_DATA; return PSMOUSE_BAD_DATA;
} }
...@@ -319,13 +312,13 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) ...@@ -319,13 +312,13 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
* There is also possibility that we got 6-byte ALPS * There is also possibility that we got 6-byte ALPS
* packet followed by 3-byte packet from trackpoint. We * packet followed by 3-byte packet from trackpoint. We
* can not distinguish between these 2 scenarios but * can not distinguish between these 2 scenarios but
* becase the latter is unlikely to happen in course of * because the latter is unlikely to happen in course of
* normal operation (user would need to press all * normal operation (user would need to press all
* buttons on the pad and start moving trackpoint * buttons on the pad and start moving trackpoint
* without touching the pad surface) we assume former. * without touching the pad surface) we assume former.
* Even if we are wrong the wost thing that would happen * Even if we are wrong the wost thing that would happen
* the cursor would jump but we should not get protocol * the cursor would jump but we should not get protocol
* desynchronization. * de-synchronization.
*/ */
alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3], alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3],
...@@ -361,10 +354,10 @@ static void alps_flush_packet(unsigned long data) ...@@ -361,10 +354,10 @@ static void alps_flush_packet(unsigned long data)
if ((psmouse->packet[3] | if ((psmouse->packet[3] |
psmouse->packet[4] | psmouse->packet[4] |
psmouse->packet[5]) & 0x80) { psmouse->packet[5]) & 0x80) {
dbg("refusing packet %x %x %x " psmouse_dbg(psmouse,
"(suspected interleaved ps/2)\n", "refusing packet %x %x %x (suspected interleaved ps/2)\n",
psmouse->packet[3], psmouse->packet[4], psmouse->packet[3], psmouse->packet[4],
psmouse->packet[5]); psmouse->packet[5]);
} else { } else {
alps_process_packet(psmouse); alps_process_packet(psmouse);
} }
...@@ -396,16 +389,18 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) ...@@ -396,16 +389,18 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
} }
if (!alps_is_valid_first_byte(model, psmouse->packet[0])) { if (!alps_is_valid_first_byte(model, psmouse->packet[0])) {
dbg("refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n", psmouse_dbg(psmouse,
psmouse->packet[0], model->mask0, model->byte0); "refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n",
psmouse->packet[0], model->mask0, model->byte0);
return PSMOUSE_BAD_DATA; return PSMOUSE_BAD_DATA;
} }
/* Bytes 2 - 6 should have 0 in the highest bit */ /* Bytes 2 - 6 should have 0 in the highest bit */
if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 && if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 &&
(psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
dbg("refusing packet[%i] = %x\n", psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
psmouse->pktcnt - 1, psmouse->packet[psmouse->pktcnt - 1]); psmouse->pktcnt - 1,
psmouse->packet[psmouse->pktcnt - 1]);
return PSMOUSE_BAD_DATA; return PSMOUSE_BAD_DATA;
} }
...@@ -439,7 +434,8 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int ...@@ -439,7 +434,8 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
return NULL; return NULL;
dbg("E6 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); psmouse_dbg(psmouse, "E6 report: %2.2x %2.2x %2.2x",
param[0], param[1], param[2]);
if (param[0] != 0 || param[1] != 0 || (param[2] != 10 && param[2] != 100)) if (param[0] != 0 || param[1] != 0 || (param[2] != 10 && param[2] != 100))
return NULL; return NULL;
...@@ -459,7 +455,8 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int ...@@ -459,7 +455,8 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
return NULL; return NULL;
dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); psmouse_dbg(psmouse, "E7 report: %2.2x %2.2x %2.2x",
param[0], param[1], param[2]);
if (version) { if (version) {
for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++) for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++)
...@@ -527,7 +524,8 @@ static int alps_get_status(struct psmouse *psmouse, char *param) ...@@ -527,7 +524,8 @@ static int alps_get_status(struct psmouse *psmouse, char *param)
ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
return -1; return -1;
dbg("Status: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); psmouse_dbg(psmouse, "Status: %2.2x %2.2x %2.2x",
param[0], param[1], param[2]);
return 0; return 0;
} }
...@@ -605,12 +603,12 @@ static int alps_hw_init(struct psmouse *psmouse) ...@@ -605,12 +603,12 @@ static int alps_hw_init(struct psmouse *psmouse)
} }
if (alps_tap_mode(psmouse, true)) { if (alps_tap_mode(psmouse, true)) {
printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); psmouse_warn(psmouse, "Failed to enable hardware tapping\n");
return -1; return -1;
} }
if (alps_absolute_mode(psmouse)) { if (alps_absolute_mode(psmouse)) {
printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); psmouse_err(psmouse, "Failed to enable absolute mode\n");
return -1; return -1;
} }
...@@ -621,7 +619,7 @@ static int alps_hw_init(struct psmouse *psmouse) ...@@ -621,7 +619,7 @@ static int alps_hw_init(struct psmouse *psmouse)
/* ALPS needs stream mode, otherwise it won't report any data */ /* ALPS needs stream mode, otherwise it won't report any data */
if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) { if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
printk(KERN_ERR "alps.c: Failed to enable stream mode\n"); psmouse_err(psmouse, "Failed to enable stream mode\n");
return -1; return -1;
} }
......
This diff is collapsed.
...@@ -16,14 +16,17 @@ ...@@ -16,14 +16,17 @@
/* /*
* Command values for Synaptics style queries * Command values for Synaptics style queries
*/ */
#define ETP_FW_ID_QUERY 0x00
#define ETP_FW_VERSION_QUERY 0x01 #define ETP_FW_VERSION_QUERY 0x01
#define ETP_CAPABILITIES_QUERY 0x02 #define ETP_CAPABILITIES_QUERY 0x02
#define ETP_SAMPLE_QUERY 0x03
/* /*
* Command values for register reading or writing * Command values for register reading or writing
*/ */
#define ETP_REGISTER_READ 0x10 #define ETP_REGISTER_READ 0x10
#define ETP_REGISTER_WRITE 0x11 #define ETP_REGISTER_WRITE 0x11
#define ETP_REGISTER_READWRITE 0x00
/* /*
* Hardware version 2 custom PS/2 command value * Hardware version 2 custom PS/2 command value
...@@ -66,16 +69,13 @@ ...@@ -66,16 +69,13 @@
#define ETP_YMAX_V1 (384 - ETP_EDGE_FUZZ_V1) #define ETP_YMAX_V1 (384 - ETP_EDGE_FUZZ_V1)
/* /*
* It seems the resolution for hardware version 2 doubled. * The resolution for older v2 hardware doubled.
* Hence the X and Y ranges are doubled too. * (newer v2's firmware provides command so we can query)
* The bezel around the pad also appears to be smaller
*/ */
#define ETP_EDGE_FUZZ_V2 8 #define ETP_XMIN_V2 0
#define ETP_XMAX_V2 1152
#define ETP_XMIN_V2 ( 0 + ETP_EDGE_FUZZ_V2) #define ETP_YMIN_V2 0
#define ETP_XMAX_V2 (1152 - ETP_EDGE_FUZZ_V2) #define ETP_YMAX_V2 768
#define ETP_YMIN_V2 ( 0 + ETP_EDGE_FUZZ_V2)
#define ETP_YMAX_V2 ( 768 - ETP_EDGE_FUZZ_V2)
#define ETP_PMIN_V2 0 #define ETP_PMIN_V2 0
#define ETP_PMAX_V2 255 #define ETP_PMAX_V2 255
...@@ -83,17 +83,37 @@ ...@@ -83,17 +83,37 @@
#define ETP_WMAX_V2 15 #define ETP_WMAX_V2 15
/* /*
* For two finger touches the coordinate of each finger gets reported * v3 hardware has 2 kinds of packet types,
* separately but with reduced resolution. * v4 hardware has 3.
*/
#define PACKET_UNKNOWN 0x01
#define PACKET_DEBOUNCE 0x02
#define PACKET_V3_HEAD 0x03
#define PACKET_V3_TAIL 0x04
#define PACKET_V4_HEAD 0x05
#define PACKET_V4_MOTION 0x06
#define PACKET_V4_STATUS 0x07
/*
* track up to 5 fingers for v4 hardware
*/
#define ETP_MAX_FINGERS 5
/*
* weight value for v4 hardware
*/ */
#define ETP_2FT_FUZZ 4 #define ETP_WEIGHT_VALUE 5
#define ETP_2FT_XMIN ( 0 + ETP_2FT_FUZZ) /*
#define ETP_2FT_XMAX (288 - ETP_2FT_FUZZ) * The base position for one finger, v4 hardware
#define ETP_2FT_YMIN ( 0 + ETP_2FT_FUZZ) */
#define ETP_2FT_YMAX (192 - ETP_2FT_FUZZ) struct finger_pos {
unsigned int x;
unsigned int y;
};
struct elantech_data { struct elantech_data {
unsigned char reg_07;
unsigned char reg_10; unsigned char reg_10;
unsigned char reg_11; unsigned char reg_11;
unsigned char reg_20; unsigned char reg_20;
...@@ -104,13 +124,16 @@ struct elantech_data { ...@@ -104,13 +124,16 @@ struct elantech_data {
unsigned char reg_25; unsigned char reg_25;
unsigned char reg_26; unsigned char reg_26;
unsigned char debug; unsigned char debug;
unsigned char capabilities; unsigned char capabilities[3];
bool paritycheck; bool paritycheck;
bool jumpy_cursor; bool jumpy_cursor;
bool reports_pressure; bool reports_pressure;
unsigned char hw_version; unsigned char hw_version;
unsigned int fw_version; unsigned int fw_version;
unsigned int single_finger_reports; unsigned int single_finger_reports;
unsigned int y_max;
unsigned int width;
struct finger_pos mt[ETP_MAX_FINGERS];
unsigned char parity[256]; unsigned char parity[256];
}; };
......
...@@ -136,10 +136,10 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y) ...@@ -136,10 +136,10 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y)
/* discard if too big, or half that but > 4 times the prev delta */ /* discard if too big, or half that but > 4 times the prev delta */
if (avx > recalib_delta || if (avx > recalib_delta ||
(avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) { (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) {
hgpk_err(psmouse, "detected %dpx jump in x\n", x); psmouse_warn(psmouse, "detected %dpx jump in x\n", x);
priv->xbigj = avx; priv->xbigj = avx;
} else if (approx_half(avx, priv->xbigj)) { } else if (approx_half(avx, priv->xbigj)) {
hgpk_err(psmouse, "detected secondary %dpx jump in x\n", x); psmouse_warn(psmouse, "detected secondary %dpx jump in x\n", x);
priv->xbigj = avx; priv->xbigj = avx;
priv->xsaw_secondary++; priv->xsaw_secondary++;
} else { } else {
...@@ -151,10 +151,10 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y) ...@@ -151,10 +151,10 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y)
if (avy > recalib_delta || if (avy > recalib_delta ||
(avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) { (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) {
hgpk_err(psmouse, "detected %dpx jump in y\n", y); psmouse_warn(psmouse, "detected %dpx jump in y\n", y);
priv->ybigj = avy; priv->ybigj = avy;
} else if (approx_half(avy, priv->ybigj)) { } else if (approx_half(avy, priv->ybigj)) {
hgpk_err(psmouse, "detected secondary %dpx jump in y\n", y); psmouse_warn(psmouse, "detected secondary %dpx jump in y\n", y);
priv->ybigj = avy; priv->ybigj = avy;
priv->ysaw_secondary++; priv->ysaw_secondary++;
} else { } else {
...@@ -168,7 +168,7 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y) ...@@ -168,7 +168,7 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y)
priv->ylast = avy; priv->ylast = avy;
if (do_recal && jumpy_delay) { if (do_recal && jumpy_delay) {
hgpk_err(psmouse, "scheduling recalibration\n"); psmouse_warn(psmouse, "scheduling recalibration\n");
psmouse_queue_work(psmouse, &priv->recalib_wq, psmouse_queue_work(psmouse, &priv->recalib_wq,
msecs_to_jiffies(jumpy_delay)); msecs_to_jiffies(jumpy_delay));
} }
...@@ -260,8 +260,8 @@ static void hgpk_spewing_hack(struct psmouse *psmouse, ...@@ -260,8 +260,8 @@ static void hgpk_spewing_hack(struct psmouse *psmouse,
* movement, it is probably a case of the user moving the * movement, it is probably a case of the user moving the
* cursor very slowly across the screen. */ * cursor very slowly across the screen. */
if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) {
hgpk_err(psmouse, "packet spew detected (%d,%d)\n", psmouse_warn(psmouse, "packet spew detected (%d,%d)\n",
priv->x_tally, priv->y_tally); priv->x_tally, priv->y_tally);
priv->spew_flag = RECALIBRATING; priv->spew_flag = RECALIBRATING;
psmouse_queue_work(psmouse, &priv->recalib_wq, psmouse_queue_work(psmouse, &priv->recalib_wq,
msecs_to_jiffies(spew_delay)); msecs_to_jiffies(spew_delay));
...@@ -333,12 +333,12 @@ static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet) ...@@ -333,12 +333,12 @@ static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet)
} }
if (!valid) if (!valid)
hgpk_dbg(psmouse, psmouse_dbg(psmouse,
"bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n", "bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n",
priv->mode, pktcnt, priv->mode, pktcnt,
psmouse->packet[0], psmouse->packet[1], psmouse->packet[0], psmouse->packet[1],
psmouse->packet[2], psmouse->packet[3], psmouse->packet[2], psmouse->packet[3],
psmouse->packet[4], psmouse->packet[5]); psmouse->packet[4], psmouse->packet[5]);
return valid; return valid;
} }
...@@ -361,19 +361,20 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse) ...@@ -361,19 +361,20 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse)
input_report_abs(idev, ABS_PRESSURE, z); input_report_abs(idev, ABS_PRESSURE, z);
if (tpdebug) if (tpdebug)
hgpk_dbg(psmouse, "pd=%d fd=%d z=%d", psmouse_dbg(psmouse, "pd=%d fd=%d z=%d",
pt_down, finger_down, z); pt_down, finger_down, z);
} else { } else {
/* /*
* PenTablet mode does not report pressure, so we don't * PenTablet mode does not report pressure, so we don't
* report it here * report it here
*/ */
if (tpdebug) if (tpdebug)
hgpk_dbg(psmouse, "pd=%d ", down); psmouse_dbg(psmouse, "pd=%d ", down);
} }
if (tpdebug) if (tpdebug)
hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y); psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n",
left, right, x, y);
input_report_key(idev, BTN_TOUCH, down); input_report_key(idev, BTN_TOUCH, down);
input_report_key(idev, BTN_LEFT, left); input_report_key(idev, BTN_LEFT, left);
...@@ -395,7 +396,7 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse) ...@@ -395,7 +396,7 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse)
if (x == priv->abs_x && y == priv->abs_y) { if (x == priv->abs_x && y == priv->abs_y) {
if (++priv->dupe_count > SPEW_WATCH_COUNT) { if (++priv->dupe_count > SPEW_WATCH_COUNT) {
if (tpdebug) if (tpdebug)
hgpk_dbg(psmouse, "hard spew detected\n"); psmouse_dbg(psmouse, "hard spew detected\n");
priv->spew_flag = RECALIBRATING; priv->spew_flag = RECALIBRATING;
psmouse_queue_work(psmouse, &priv->recalib_wq, psmouse_queue_work(psmouse, &priv->recalib_wq,
msecs_to_jiffies(spew_delay)); msecs_to_jiffies(spew_delay));
...@@ -412,7 +413,7 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse) ...@@ -412,7 +413,7 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse)
int y_diff = priv->abs_y - y; int y_diff = priv->abs_y - y;
if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) { if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) {
if (tpdebug) if (tpdebug)
hgpk_dbg(psmouse, "discarding\n"); psmouse_dbg(psmouse, "discarding\n");
goto done; goto done;
} }
hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff); hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff);
...@@ -437,20 +438,21 @@ static void hgpk_process_simple_packet(struct psmouse *psmouse) ...@@ -437,20 +438,21 @@ static void hgpk_process_simple_packet(struct psmouse *psmouse)
int y = ((packet[0] << 3) & 0x100) - packet[2]; int y = ((packet[0] << 3) & 0x100) - packet[2];
if (packet[0] & 0xc0) if (packet[0] & 0xc0)
hgpk_dbg(psmouse, psmouse_dbg(psmouse,
"overflow -- 0x%02x 0x%02x 0x%02x\n", "overflow -- 0x%02x 0x%02x 0x%02x\n",
packet[0], packet[1], packet[2]); packet[0], packet[1], packet[2]);
if (hgpk_discard_decay_hack(psmouse, x, y)) { if (hgpk_discard_decay_hack(psmouse, x, y)) {
if (tpdebug) if (tpdebug)
hgpk_dbg(psmouse, "discarding\n"); psmouse_dbg(psmouse, "discarding\n");
return; return;
} }
hgpk_spewing_hack(psmouse, left, right, x, y); hgpk_spewing_hack(psmouse, left, right, x, y);
if (tpdebug) if (tpdebug)
hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y); psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n",
left, right, x, y);
input_report_key(dev, BTN_LEFT, left); input_report_key(dev, BTN_LEFT, left);
input_report_key(dev, BTN_RIGHT, right); input_report_key(dev, BTN_RIGHT, right);
...@@ -482,9 +484,8 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse) ...@@ -482,9 +484,8 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
* ugh, got a packet inside our recalibration * ugh, got a packet inside our recalibration
* window, schedule another recalibration. * window, schedule another recalibration.
*/ */
hgpk_dbg(psmouse, psmouse_dbg(psmouse,
"packet inside calibration window, " "packet inside calibration window, queueing another recalibration\n");
"queueing another recalibration\n");
psmouse_queue_work(psmouse, &priv->recalib_wq, psmouse_queue_work(psmouse, &priv->recalib_wq,
msecs_to_jiffies(post_interrupt_delay)); msecs_to_jiffies(post_interrupt_delay));
} }
...@@ -628,7 +629,7 @@ static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate) ...@@ -628,7 +629,7 @@ static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate)
err = hgpk_select_mode(psmouse); err = hgpk_select_mode(psmouse);
if (err) { if (err) {
hgpk_err(psmouse, "failed to select mode\n"); psmouse_err(psmouse, "failed to select mode\n");
return err; return err;
} }
...@@ -648,11 +649,11 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse) ...@@ -648,11 +649,11 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse)
return 0; return 0;
if (!autorecal) { if (!autorecal) {
hgpk_dbg(psmouse, "recalibrations disabled, ignoring\n"); psmouse_dbg(psmouse, "recalibration disabled, ignoring\n");
return 0; return 0;
} }
hgpk_dbg(psmouse, "recalibrating touchpad..\n"); psmouse_dbg(psmouse, "recalibrating touchpad..\n");
/* we don't want to race with the irq handler, nor with resyncs */ /* we don't want to race with the irq handler, nor with resyncs */
psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
...@@ -675,7 +676,7 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse) ...@@ -675,7 +676,7 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse)
psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
if (tpdebug) if (tpdebug)
hgpk_dbg(psmouse, "touchpad reactivated\n"); psmouse_dbg(psmouse, "touchpad reactivated\n");
/* /*
* If we get packets right away after recalibrating, it's likely * If we get packets right away after recalibrating, it's likely
...@@ -727,16 +728,16 @@ static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable) ...@@ -727,16 +728,16 @@ static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable)
err = hgpk_reset_device(psmouse, false); err = hgpk_reset_device(psmouse, false);
if (err) { if (err) {
hgpk_err(psmouse, "Failed to reset device!\n"); psmouse_err(psmouse, "Failed to reset device!\n");
return err; return err;
} }
/* should be all set, enable the touchpad */ /* should be all set, enable the touchpad */
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);
psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
hgpk_dbg(psmouse, "Touchpad powered up.\n"); psmouse_dbg(psmouse, "Touchpad powered up.\n");
} else { } else {
hgpk_dbg(psmouse, "Powering off touchpad.\n"); psmouse_dbg(psmouse, "Powering off touchpad.\n");
if (ps2_command(ps2dev, NULL, 0xec) || if (ps2_command(ps2dev, NULL, 0xec) ||
ps2_command(ps2dev, NULL, 0xec) || ps2_command(ps2dev, NULL, 0xec) ||
...@@ -923,7 +924,7 @@ static void hgpk_recalib_work(struct work_struct *work) ...@@ -923,7 +924,7 @@ static void hgpk_recalib_work(struct work_struct *work)
struct psmouse *psmouse = priv->psmouse; struct psmouse *psmouse = priv->psmouse;
if (hgpk_force_recalibrate(psmouse)) if (hgpk_force_recalibrate(psmouse))
hgpk_err(psmouse, "recalibration failed!\n"); psmouse_err(psmouse, "recalibration failed!\n");
} }
static int hgpk_register(struct psmouse *psmouse) static int hgpk_register(struct psmouse *psmouse)
...@@ -947,14 +948,15 @@ static int hgpk_register(struct psmouse *psmouse) ...@@ -947,14 +948,15 @@ static int hgpk_register(struct psmouse *psmouse)
err = device_create_file(&psmouse->ps2dev.serio->dev, err = device_create_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_powered.dattr); &psmouse_attr_powered.dattr);
if (err) { if (err) {
hgpk_err(psmouse, "Failed creating 'powered' sysfs node\n"); psmouse_err(psmouse, "Failed creating 'powered' sysfs node\n");
return err; return err;
} }
err = device_create_file(&psmouse->ps2dev.serio->dev, err = device_create_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_hgpk_mode.dattr); &psmouse_attr_hgpk_mode.dattr);
if (err) { if (err) {
hgpk_err(psmouse, "Failed creating 'hgpk_mode' sysfs node\n"); psmouse_err(psmouse,
"Failed creating 'hgpk_mode' sysfs node\n");
goto err_remove_powered; goto err_remove_powered;
} }
...@@ -963,8 +965,8 @@ static int hgpk_register(struct psmouse *psmouse) ...@@ -963,8 +965,8 @@ static int hgpk_register(struct psmouse *psmouse)
err = device_create_file(&psmouse->ps2dev.serio->dev, err = device_create_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_recalibrate.dattr); &psmouse_attr_recalibrate.dattr);
if (err) { if (err) {
hgpk_err(psmouse, psmouse_err(psmouse,
"Failed creating 'recalibrate' sysfs node\n"); "Failed creating 'recalibrate' sysfs node\n");
goto err_remove_mode; goto err_remove_mode;
} }
} }
...@@ -1027,13 +1029,13 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse) ...@@ -1027,13 +1029,13 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
return -EIO; return -EIO;
} }
hgpk_dbg(psmouse, "ID: %02x %02x %02x\n", param[0], param[1], param[2]); psmouse_dbg(psmouse, "ID: %02x %02x %02x\n", param[0], param[1], param[2]);
/* HGPK signature: 0x67, 0x00, 0x<model> */ /* HGPK signature: 0x67, 0x00, 0x<model> */
if (param[0] != 0x67 || param[1] != 0x00) if (param[0] != 0x67 || param[1] != 0x00)
return -ENODEV; return -ENODEV;
hgpk_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]); psmouse_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]);
return param[2]; return param[2];
} }
......
...@@ -46,17 +46,6 @@ struct hgpk_data { ...@@ -46,17 +46,6 @@ struct hgpk_data {
int xsaw_secondary, ysaw_secondary; /* jumpiness detection */ int xsaw_secondary, ysaw_secondary; /* jumpiness detection */
}; };
#define hgpk_dbg(psmouse, format, arg...) \
dev_dbg(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_err(psmouse, format, arg...) \
dev_err(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_info(psmouse, format, arg...) \
dev_info(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_warn(psmouse, format, arg...) \
dev_warn(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_notice(psmouse, format, arg...) \
dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#ifdef CONFIG_MOUSE_PS2_OLPC #ifdef CONFIG_MOUSE_PS2_OLPC
void hgpk_module_init(void); void hgpk_module_init(void);
int hgpk_detect(struct psmouse *psmouse, bool set_properties); int hgpk_detect(struct psmouse *psmouse, bool set_properties);
......
...@@ -169,8 +169,8 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) ...@@ -169,8 +169,8 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
if (relative_packet) { if (relative_packet) {
if (!dev2) if (!dev2)
printk(KERN_WARNING "lifebook.c: got relative packet " psmouse_warn(psmouse,
"but no relative device set up\n"); "got relative packet but no relative device set up\n");
} else { } else {
if (lifebook_use_6byte_proto) { if (lifebook_use_6byte_proto) {
input_report_abs(dev1, ABS_X, input_report_abs(dev1, ABS_X,
...@@ -212,7 +212,7 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) ...@@ -212,7 +212,7 @@ static int lifebook_absolute_mode(struct psmouse *psmouse)
/* /*
* Enable absolute output -- ps2_command fails always but if * Enable absolute output -- ps2_command fails always but if
* you leave this call out the touchsreen will never send * you leave this call out the touchscreen will never send
* absolute coordinates * absolute coordinates
*/ */
param = lifebook_use_6byte_proto ? 0x08 : 0x07; param = lifebook_use_6byte_proto ? 0x08 : 0x07;
......
...@@ -82,11 +82,11 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) ...@@ -82,11 +82,11 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
packet[0] = packet[2] | 0x08; packet[0] = packet[2] | 0x08;
break; break;
#ifdef DEBUG
default: default:
printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n", psmouse_dbg(psmouse,
(packet[1] >> 4) | (packet[0] & 0x30)); "Received PS2++ packet #%x, but don't know how to handle.\n",
#endif (packet[1] >> 4) | (packet[0] & 0x30));
break;
} }
} else { } else {
/* Standard PS/2 motion data */ /* Standard PS/2 motion data */
...@@ -382,7 +382,7 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) ...@@ -382,7 +382,7 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties)
} }
} else { } else {
printk(KERN_WARNING "logips2pp: Detected unknown logitech mouse model %d\n", model); psmouse_warn(psmouse, "Detected unknown Logitech mouse model %d\n", model);
} }
if (set_properties) { if (set_properties) {
...@@ -400,9 +400,9 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) ...@@ -400,9 +400,9 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties)
error = device_create_file(&psmouse->ps2dev.serio->dev, error = device_create_file(&psmouse->ps2dev.serio->dev,
&psmouse_attr_smartscroll.dattr); &psmouse_attr_smartscroll.dattr);
if (error) { if (error) {
printk(KERN_ERR psmouse_err(psmouse,
"logips2pp.c: failed to create smartscroll " "failed to create smartscroll sysfs attribute, error: %d\n",
"sysfs attribute, error: %d\n", error); error);
return -1; return -1;
} }
} }
......
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
* the Free Software Foundation. * the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define psmouse_fmt(fmt) fmt
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -251,11 +254,14 @@ static int psmouse_handle_byte(struct psmouse *psmouse) ...@@ -251,11 +254,14 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
switch (rc) { switch (rc) {
case PSMOUSE_BAD_DATA: case PSMOUSE_BAD_DATA:
if (psmouse->state == PSMOUSE_ACTIVATED) { if (psmouse->state == PSMOUSE_ACTIVATED) {
printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", psmouse_warn(psmouse,
psmouse->name, psmouse->phys, psmouse->pktcnt); "%s at %s lost sync at byte %d\n",
psmouse->name, psmouse->phys,
psmouse->pktcnt);
if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { if (++psmouse->out_of_sync_cnt == psmouse->resetafter) {
__psmouse_set_state(psmouse, PSMOUSE_IGNORE); __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); psmouse_notice(psmouse,
"issuing reconnect request\n");
serio_reconnect(psmouse->ps2dev.serio); serio_reconnect(psmouse->ps2dev.serio);
return -1; return -1;
} }
...@@ -267,8 +273,9 @@ static int psmouse_handle_byte(struct psmouse *psmouse) ...@@ -267,8 +273,9 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
psmouse->pktcnt = 0; psmouse->pktcnt = 0;
if (psmouse->out_of_sync_cnt) { if (psmouse->out_of_sync_cnt) {
psmouse->out_of_sync_cnt = 0; psmouse->out_of_sync_cnt = 0;
printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", psmouse_notice(psmouse,
psmouse->name, psmouse->phys); "%s at %s - driver resynced.\n",
psmouse->name, psmouse->phys);
} }
break; break;
...@@ -295,9 +302,10 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -295,9 +302,10 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
((flags & SERIO_PARITY) && !psmouse->ignore_parity))) { ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) {
if (psmouse->state == PSMOUSE_ACTIVATED) if (psmouse->state == PSMOUSE_ACTIVATED)
printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", psmouse_warn(psmouse,
flags & SERIO_TIMEOUT ? " timeout" : "", "bad data from KBC -%s%s\n",
flags & SERIO_PARITY ? " bad parity" : ""); flags & SERIO_TIMEOUT ? " timeout" : "",
flags & SERIO_PARITY ? " bad parity" : "");
ps2_cmd_aborted(&psmouse->ps2dev); ps2_cmd_aborted(&psmouse->ps2dev);
goto out; goto out;
} }
...@@ -315,8 +323,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -315,8 +323,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
if (psmouse->state == PSMOUSE_ACTIVATED && if (psmouse->state == PSMOUSE_ACTIVATED &&
psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
printk(KERN_INFO "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n", psmouse_info(psmouse, "%s at %s lost synchronization, throwing %d bytes away.\n",
psmouse->name, psmouse->phys, psmouse->pktcnt); psmouse->name, psmouse->phys, psmouse->pktcnt);
psmouse->badbyte = psmouse->packet[0]; psmouse->badbyte = psmouse->packet[0];
__psmouse_set_state(psmouse, PSMOUSE_RESYNCING); __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
psmouse_queue_work(psmouse, &psmouse->resync_work, 0); psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
...@@ -943,7 +951,8 @@ static int psmouse_probe(struct psmouse *psmouse) ...@@ -943,7 +951,8 @@ static int psmouse_probe(struct psmouse *psmouse)
*/ */
if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS)) if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS))
printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", ps2dev->serio->phys); psmouse_warn(psmouse, "Failed to reset mouse on %s\n",
ps2dev->serio->phys);
return 0; return 0;
} }
...@@ -1005,8 +1014,8 @@ static void psmouse_initialize(struct psmouse *psmouse) ...@@ -1005,8 +1014,8 @@ static void psmouse_initialize(struct psmouse *psmouse)
static void psmouse_activate(struct psmouse *psmouse) static void psmouse_activate(struct psmouse *psmouse)
{ {
if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE))
printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", psmouse_warn(psmouse, "Failed to enable mouse on %s\n",
psmouse->ps2dev.serio->phys); psmouse->ps2dev.serio->phys);
psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
} }
...@@ -1020,14 +1029,14 @@ static void psmouse_activate(struct psmouse *psmouse) ...@@ -1020,14 +1029,14 @@ static void psmouse_activate(struct psmouse *psmouse)
static void psmouse_deactivate(struct psmouse *psmouse) static void psmouse_deactivate(struct psmouse *psmouse)
{ {
if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE))
printk(KERN_WARNING "psmouse.c: Failed to deactivate mouse on %s\n", psmouse_warn(psmouse, "Failed to deactivate mouse on %s\n",
psmouse->ps2dev.serio->phys); psmouse->ps2dev.serio->phys);
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
} }
/* /*
* psmouse_poll() - default poll hanlder. Everyone except for ALPS uses it. * psmouse_poll() - default poll handler. Everyone except for ALPS uses it.
*/ */
static int psmouse_poll(struct psmouse *psmouse) static int psmouse_poll(struct psmouse *psmouse)
...@@ -1115,14 +1124,15 @@ static void psmouse_resync(struct work_struct *work) ...@@ -1115,14 +1124,15 @@ static void psmouse_resync(struct work_struct *work)
} }
if (!enabled) { if (!enabled) {
printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n", psmouse_warn(psmouse, "failed to re-enable mouse on %s\n",
psmouse->ps2dev.serio->phys); psmouse->ps2dev.serio->phys);
failed = true; failed = true;
} }
if (failed) { if (failed) {
psmouse_set_state(psmouse, PSMOUSE_IGNORE); psmouse_set_state(psmouse, PSMOUSE_IGNORE);
printk(KERN_INFO "psmouse.c: resync failed, issuing reconnect request\n"); psmouse_info(psmouse,
"resync failed, issuing reconnect request\n");
serio_reconnect(serio); serio_reconnect(serio);
} else } else
psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
...@@ -1155,8 +1165,8 @@ static void psmouse_cleanup(struct serio *serio) ...@@ -1155,8 +1165,8 @@ static void psmouse_cleanup(struct serio *serio)
* Disable stream mode so cleanup routine can proceed undisturbed. * Disable stream mode so cleanup routine can proceed undisturbed.
*/ */
if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE))
printk(KERN_WARNING "psmouse.c: Failed to disable mouse on %s\n", psmouse_warn(psmouse, "Failed to disable mouse on %s\n",
psmouse->ps2dev.serio->phys); psmouse->ps2dev.serio->phys);
if (psmouse->cleanup) if (psmouse->cleanup)
psmouse->cleanup(psmouse); psmouse->cleanup(psmouse);
...@@ -1400,7 +1410,8 @@ static int psmouse_reconnect(struct serio *serio) ...@@ -1400,7 +1410,8 @@ static int psmouse_reconnect(struct serio *serio)
int rc = -1; int rc = -1;
if (!drv || !psmouse) { if (!drv || !psmouse) {
printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n"); psmouse_dbg(psmouse,
"reconnect request, but serio is disconnected, ignoring...\n");
return -1; return -1;
} }
...@@ -1427,8 +1438,9 @@ static int psmouse_reconnect(struct serio *serio) ...@@ -1427,8 +1438,9 @@ static int psmouse_reconnect(struct serio *serio)
goto out; goto out;
} }
/* ok, the device type (and capabilities) match the old one, /*
* we can continue using it, complete intialization * OK, the device type (and capabilities) match the old one,
* we can continue using it, complete initialization
*/ */
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
...@@ -1586,9 +1598,8 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co ...@@ -1586,9 +1598,8 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
while (!list_empty(&serio->children)) { while (!list_empty(&serio->children)) {
if (++retry > 3) { if (++retry > 3) {
printk(KERN_WARNING psmouse_warn(psmouse,
"psmouse: failed to destroy children ports, " "failed to destroy children ports, protocol change aborted.\n");
"protocol change aborted.\n");
input_free_device(new_dev); input_free_device(new_dev);
return -EIO; return -EIO;
} }
...@@ -1715,7 +1726,7 @@ static int __init psmouse_init(void) ...@@ -1715,7 +1726,7 @@ static int __init psmouse_init(void)
kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); kpsmoused_wq = create_singlethread_workqueue("kpsmoused");
if (!kpsmoused_wq) { if (!kpsmoused_wq) {
printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); pr_err("failed to create kpsmoused workqueue\n");
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -150,4 +150,29 @@ static struct psmouse_attribute psmouse_attr_##_name = { \ ...@@ -150,4 +150,29 @@ static struct psmouse_attribute psmouse_attr_##_name = { \
static ssize_t _set(struct psmouse *, void *, const char *, size_t); \ static ssize_t _set(struct psmouse *, void *, const char *, size_t); \
__PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, NULL, _set, true) __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, NULL, _set, true)
#ifndef psmouse_fmt
#define psmouse_fmt(fmt) KBUILD_BASENAME ": " fmt
#endif
#define psmouse_dbg(psmouse, format, ...) \
dev_dbg(&(psmouse)->ps2dev.serio->dev, \
psmouse_fmt(format), ##__VA_ARGS__)
#define psmouse_info(psmouse, format, ...) \
dev_info(&(psmouse)->ps2dev.serio->dev, \
psmouse_fmt(format), ##__VA_ARGS__)
#define psmouse_warn(psmouse, format, ...) \
dev_warn(&(psmouse)->ps2dev.serio->dev, \
psmouse_fmt(format), ##__VA_ARGS__)
#define psmouse_err(psmouse, format, ...) \
dev_err(&(psmouse)->ps2dev.serio->dev, \
psmouse_fmt(format), ##__VA_ARGS__)
#define psmouse_notice(psmouse, format, ...) \
dev_notice(&(psmouse)->ps2dev.serio->dev, \
psmouse_fmt(format), ##__VA_ARGS__)
#define psmouse_printk(level, psmouse, format, ...) \
dev_printk(level, \
&(psmouse)->ps2dev.serio->dev, \
psmouse_fmt(format), ##__VA_ARGS__)
#endif /* _PSMOUSE_H */ #endif /* _PSMOUSE_H */
...@@ -183,7 +183,7 @@ static int __devinit pxa930_trkball_probe(struct platform_device *pdev) ...@@ -183,7 +183,7 @@ static int __devinit pxa930_trkball_probe(struct platform_device *pdev)
/* held the module in reset, will be enabled in open() */ /* held the module in reset, will be enabled in open() */
pxa930_trkball_disable(trkball); pxa930_trkball_disable(trkball);
error = request_irq(irq, pxa930_trkball_interrupt, IRQF_DISABLED, error = request_irq(irq, pxa930_trkball_interrupt, 0,
pdev->name, trkball); pdev->name, trkball);
if (error) { if (error) {
dev_err(&pdev->dev, "failed to request irq: %d\n", error); dev_err(&pdev->dev, "failed to request irq: %d\n", error);
......
...@@ -607,11 +607,12 @@ static void fsp_packet_debug(unsigned char packet[]) ...@@ -607,11 +607,12 @@ static void fsp_packet_debug(unsigned char packet[])
ps2_packet_cnt++; ps2_packet_cnt++;
jiffies_msec = jiffies_to_msecs(jiffies); jiffies_msec = jiffies_to_msecs(jiffies);
printk(KERN_DEBUG "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n", psmouse_dbg(psmouse,
jiffies_msec, packet[0], packet[1], packet[2], packet[3]); "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n",
jiffies_msec, packet[0], packet[1], packet[2], packet[3]);
if (jiffies_msec - ps2_last_second > 1000) { if (jiffies_msec - ps2_last_second > 1000) {
printk(KERN_DEBUG "PS/2 packets/sec = %d\n", ps2_packet_cnt); psmouse_dbg(psmouse, "PS/2 packets/sec = %d\n", ps2_packet_cnt);
ps2_packet_cnt = 0; ps2_packet_cnt = 0;
ps2_last_second = jiffies_msec; ps2_last_second = jiffies_msec;
} }
...@@ -820,9 +821,9 @@ int fsp_init(struct psmouse *psmouse) ...@@ -820,9 +821,9 @@ int fsp_init(struct psmouse *psmouse)
return -ENODEV; return -ENODEV;
} }
printk(KERN_INFO psmouse_info(psmouse,
"Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n", "Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n",
ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7); ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7);
psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL);
if (!priv) if (!priv)
......
This diff is collapsed.
...@@ -74,6 +74,8 @@ ...@@ -74,6 +74,8 @@
* 2 0x04 reduced filtering firmware does less filtering on * 2 0x04 reduced filtering firmware does less filtering on
* position data, driver should watch * position data, driver should watch
* for noise. * for noise.
* 2 0x08 image sensor image sensor tracks 5 fingers, but only
* reports 2.
* 2 0x20 report min query 0x0f gives min coord reported * 2 0x20 report min query 0x0f gives min coord reported
*/ */
#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */
...@@ -82,6 +84,7 @@ ...@@ -82,6 +84,7 @@
#define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & 0x002000) #define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & 0x002000)
#define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000)
#define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400)
#define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800)
/* synaptics modes query bits */ /* synaptics modes query bits */
#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7))
...@@ -112,9 +115,18 @@ ...@@ -112,9 +115,18 @@
#define SYN_REDUCED_FILTER_FUZZ 8 #define SYN_REDUCED_FILTER_FUZZ 8
/* /*
* A structure to describe the state of the touchpad hardware (buttons and pad) * A structure to describe which internal touchpad finger slots are being
* reported in raw packets.
*/ */
struct synaptics_mt_state {
int count; /* num fingers being tracked */
int sgm; /* which slot is reported by sgm pkt */
int agm; /* which slot is reported by agm pkt*/
};
/*
* A structure to describe the state of the touchpad hardware (buttons and pad)
*/
struct synaptics_hw_state { struct synaptics_hw_state {
int x; int x;
int y; int y;
...@@ -127,6 +139,9 @@ struct synaptics_hw_state { ...@@ -127,6 +139,9 @@ struct synaptics_hw_state {
unsigned int down:1; unsigned int down:1;
unsigned char ext_buttons; unsigned char ext_buttons;
signed char scroll; signed char scroll;
/* As reported in last AGM-CONTACT packets */
struct synaptics_mt_state mt_state;
}; };
struct synaptics_data { struct synaptics_data {
...@@ -146,7 +161,15 @@ struct synaptics_data { ...@@ -146,7 +161,15 @@ struct synaptics_data {
struct serio *pt_port; /* Pass-through serio port */ struct serio *pt_port; /* Pass-through serio port */
struct synaptics_hw_state mt; /* current gesture packet */ struct synaptics_mt_state mt_state; /* Current mt finger state */
bool mt_state_lost; /* mt_state may be incorrect */
/*
* Last received Advanced Gesture Mode (AGM) packet. An AGM packet
* contains position data for a second contact, at half resolution.
*/
struct synaptics_hw_state agm;
bool agm_pending; /* new AGM packet received */
}; };
void synaptics_module_init(void); void synaptics_module_init(void);
......
...@@ -570,7 +570,7 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client, ...@@ -570,7 +570,7 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client,
"Requesting IRQ: %d\n", touch->client->irq); "Requesting IRQ: %d\n", touch->client->irq);
ret = request_irq(touch->client->irq, synaptics_i2c_irq, ret = request_irq(touch->client->irq, synaptics_i2c_irq,
IRQF_DISABLED|IRQ_TYPE_EDGE_FALLING, IRQ_TYPE_EDGE_FALLING,
DRIVER_NAME, touch); DRIVER_NAME, touch);
if (ret) { if (ret) {
dev_warn(&touch->client->dev, dev_warn(&touch->client->dev,
...@@ -619,7 +619,7 @@ static int __devexit synaptics_i2c_remove(struct i2c_client *client) ...@@ -619,7 +619,7 @@ static int __devexit synaptics_i2c_remove(struct i2c_client *client)
return 0; return 0;
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP
static int synaptics_i2c_suspend(struct device *dev) static int synaptics_i2c_suspend(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
......
This diff is collapsed.
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* Copyright (c) 2000 Daniel Egger <egger@suse.de> * Copyright (c) 2000 Daniel Egger <egger@suse.de>
* Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
* Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
* Copyright (c) 2002-2009 Ping Cheng <pingc@wacom.com> * Copyright (c) 2002-2011 Ping Cheng <pingc@wacom.com>
* *
* ChangeLog: * ChangeLog:
* v0.1 (vp) - Initial release * v0.1 (vp) - Initial release
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
/* /*
* Version Information * Version Information
*/ */
#define DRIVER_VERSION "v1.52" #define DRIVER_VERSION "v1.53"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
#define DRIVER_DESC "USB Wacom tablet driver" #define DRIVER_DESC "USB Wacom tablet driver"
#define DRIVER_LICENSE "GPL" #define DRIVER_LICENSE "GPL"
...@@ -114,6 +114,12 @@ struct wacom { ...@@ -114,6 +114,12 @@ struct wacom {
struct mutex lock; struct mutex lock;
bool open; bool open;
char phys[32]; char phys[32];
struct wacom_led {
u8 select[2]; /* status led selector (0..3) */
u8 llv; /* status led brightness no button (1..127) */
u8 hlv; /* status led brightness button pressed (1..127) */
u8 img_lum; /* OLED matrix display brightness */
} led;
}; };
extern const struct usb_device_id wacom_ids[]; extern const struct usb_device_id wacom_ids[];
......
This diff is collapsed.
...@@ -874,7 +874,15 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) ...@@ -874,7 +874,15 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
x = le16_to_cpup((__le16 *)&data[2]); x = le16_to_cpup((__le16 *)&data[2]);
y = le16_to_cpup((__le16 *)&data[4]); y = le16_to_cpup((__le16 *)&data[4]);
p = le16_to_cpup((__le16 *)&data[6]); p = le16_to_cpup((__le16 *)&data[6]);
d = data[8]; /*
* Convert distance from out prox to distance from tablet.
* distance will be greater than distance_max once
* touching and applying pressure; do not report negative
* distance.
*/
if (data[8] <= wacom->features.distance_max)
d = wacom->features.distance_max - data[8];
pen = data[1] & 0x01; pen = data[1] & 0x01;
btn1 = data[1] & 0x02; btn1 = data[1] & 0x02;
btn2 = data[1] & 0x04; btn2 = data[1] & 0x04;
...@@ -1030,8 +1038,6 @@ void wacom_setup_device_quirks(struct wacom_features *features) ...@@ -1030,8 +1038,6 @@ void wacom_setup_device_quirks(struct wacom_features *features)
features->y_max <<= 5; features->y_max <<= 5;
features->x_fuzz <<= 5; features->x_fuzz <<= 5;
features->y_fuzz <<= 5; features->y_fuzz <<= 5;
features->pressure_max = 256;
features->pressure_fuzz = 16;
features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES; features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES;
} }
} }
...@@ -1241,14 +1247,14 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, ...@@ -1241,14 +1247,14 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
0, features->y_max, 0, features->y_max,
features->y_fuzz, 0); features->y_fuzz, 0);
input_set_abs_params(input_dev, ABS_MT_PRESSURE,
0, features->pressure_max,
features->pressure_fuzz, 0);
} else if (features->device_type == BTN_TOOL_PEN) { } else if (features->device_type == BTN_TOOL_PEN) {
__set_bit(BTN_TOOL_RUBBER, input_dev->keybit); __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
__set_bit(BTN_TOOL_PEN, input_dev->keybit); __set_bit(BTN_TOOL_PEN, input_dev->keybit);
__set_bit(BTN_STYLUS, input_dev->keybit); __set_bit(BTN_STYLUS, input_dev->keybit);
__set_bit(BTN_STYLUS2, input_dev->keybit); __set_bit(BTN_STYLUS2, input_dev->keybit);
input_set_abs_params(input_dev, ABS_DISTANCE, 0,
features->distance_max,
0, 0);
} }
break; break;
} }
...@@ -1469,37 +1475,37 @@ static const struct wacom_features wacom_features_0x47 = ...@@ -1469,37 +1475,37 @@ static const struct wacom_features wacom_features_0x47 =
31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD0 = static const struct wacom_features wacom_features_0xD0 =
{ "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD1 = static const struct wacom_features wacom_features_0xD1 =
{ "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, { "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD2 = static const struct wacom_features wacom_features_0xD2 =
{ "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD3 = static const struct wacom_features wacom_features_0xD3 =
{ "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD4 = static const struct wacom_features wacom_features_0xD4 =
{ "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD5 = static const struct wacom_features wacom_features_0xD5 =
{ "Wacom Bamboo Pen 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, { "Wacom Bamboo Pen 6x8", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD6 = static const struct wacom_features wacom_features_0xD6 =
{ "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD7 = static const struct wacom_features wacom_features_0xD7 =
{ "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, { "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD8 = static const struct wacom_features wacom_features_0xD8 =
{ "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xDA = static const struct wacom_features wacom_features_0xDA =
{ "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static struct wacom_features wacom_features_0xDB = static struct wacom_features wacom_features_0xDB =
{ "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x6004 = static const struct wacom_features wacom_features_0x6004 =
{ "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255,
0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
......
...@@ -651,6 +651,18 @@ config TOUCHSCREEN_TOUCHIT213 ...@@ -651,6 +651,18 @@ config TOUCHSCREEN_TOUCHIT213
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called touchit213. module will be called touchit213.
config TOUCHSCREEN_TSC_SERIO
tristate "TSC-10/25/40 serial touchscreen support"
select SERIO
help
Say Y here if you have a TSC-10, 25 or 40 serial touchscreen connected
to your system.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called tsc40.
config TOUCHSCREEN_TSC2005 config TOUCHSCREEN_TSC2005
tristate "TSC2005 based touchscreens" tristate "TSC2005 based touchscreens"
depends on SPI_MASTER && GENERIC_HARDIRQS depends on SPI_MASTER && GENERIC_HARDIRQS
......
...@@ -46,6 +46,7 @@ obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o ...@@ -46,6 +46,7 @@ obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
obj-$(CONFIG_TOUCHSCREEN_TSC_SERIO) += tsc40.o
obj-$(CONFIG_TOUCHSCREEN_TSC2005) += tsc2005.o obj-$(CONFIG_TOUCHSCREEN_TSC2005) += tsc2005.o
obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o
obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
......
This diff is collapsed.
This diff is collapsed.
...@@ -229,7 +229,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev) ...@@ -229,7 +229,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
goto err_release_mem; goto err_release_mem;
} }
err = request_irq(ts_dev->irq, atmel_tsadcc_interrupt, IRQF_DISABLED, err = request_irq(ts_dev->irq, atmel_tsadcc_interrupt, 0,
pdev->dev.driver->name, ts_dev); pdev->dev.driver->name, ts_dev);
if (err) { if (err) {
dev_err(&pdev->dev, "failed to allocate irq.\n"); dev_err(&pdev->dev, "failed to allocate irq.\n");
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -199,5 +199,6 @@ static inline void serio_continue_rx(struct serio *serio) ...@@ -199,5 +199,6 @@ static inline void serio_continue_rx(struct serio *serio)
#define SERIO_DYNAPRO 0x3a #define SERIO_DYNAPRO 0x3a
#define SERIO_HAMPSHIRE 0x3b #define SERIO_HAMPSHIRE 0x3b
#define SERIO_PS2MULT 0x3c #define SERIO_PS2MULT 0x3c
#define SERIO_TSC40 0x3d
#endif #endif
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment