Input: appletouch - implement reset-resume logic
On some boxes the touchpad needs to be reinitialized after resume to make it function again. This fixes bugzilla #10825. Signed-off-by: Oliver Neukum <oneukum@suse.de> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
parent
2f6a77d565
commit
90d95ef617
@ -589,6 +589,21 @@ static void atp_close(struct input_dev *input)
|
|||||||
dev->open = 0;
|
dev->open = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int atp_handle_geyser(struct atp *dev)
|
||||||
|
{
|
||||||
|
struct usb_device *udev = dev->udev;
|
||||||
|
|
||||||
|
if (!atp_is_fountain(dev)) {
|
||||||
|
/* switch to raw sensor mode */
|
||||||
|
if (atp_geyser_init(udev))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
printk(KERN_INFO "appletouch: Geyser mode initialized.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
|
static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
struct atp *dev;
|
struct atp *dev;
|
||||||
@ -633,14 +648,6 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
|
|||||||
else
|
else
|
||||||
dev->datalen = 81;
|
dev->datalen = 81;
|
||||||
|
|
||||||
if (!atp_is_fountain(dev)) {
|
|
||||||
/* switch to raw sensor mode */
|
|
||||||
if (atp_geyser_init(udev))
|
|
||||||
goto err_free_devs;
|
|
||||||
|
|
||||||
printk(KERN_INFO "appletouch: Geyser mode initialized.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->urb = usb_alloc_urb(0, GFP_KERNEL);
|
dev->urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||||
if (!dev->urb)
|
if (!dev->urb)
|
||||||
goto err_free_devs;
|
goto err_free_devs;
|
||||||
@ -654,6 +661,10 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
|
|||||||
usb_rcvintpipe(udev, int_in_endpointAddr),
|
usb_rcvintpipe(udev, int_in_endpointAddr),
|
||||||
dev->data, dev->datalen, atp_complete, dev, 1);
|
dev->data, dev->datalen, atp_complete, dev, 1);
|
||||||
|
|
||||||
|
error = atp_handle_geyser(dev);
|
||||||
|
if (error)
|
||||||
|
goto err_free_buffer;
|
||||||
|
|
||||||
usb_make_path(udev, dev->phys, sizeof(dev->phys));
|
usb_make_path(udev, dev->phys, sizeof(dev->phys));
|
||||||
strlcat(dev->phys, "/input0", sizeof(dev->phys));
|
strlcat(dev->phys, "/input0", sizeof(dev->phys));
|
||||||
|
|
||||||
@ -744,6 +755,20 @@ static void atp_disconnect(struct usb_interface *iface)
|
|||||||
printk(KERN_INFO "input: appletouch disconnected\n");
|
printk(KERN_INFO "input: appletouch disconnected\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int atp_recover(struct atp *dev)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = atp_handle_geyser(dev);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int atp_suspend(struct usb_interface *iface, pm_message_t message)
|
static int atp_suspend(struct usb_interface *iface, pm_message_t message)
|
||||||
{
|
{
|
||||||
struct atp *dev = usb_get_intfdata(iface);
|
struct atp *dev = usb_get_intfdata(iface);
|
||||||
@ -764,12 +789,20 @@ static int atp_resume(struct usb_interface *iface)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int atp_reset_resume(struct usb_interface *iface)
|
||||||
|
{
|
||||||
|
struct atp *dev = usb_get_intfdata(iface);
|
||||||
|
|
||||||
|
return atp_recover(dev);
|
||||||
|
}
|
||||||
|
|
||||||
static struct usb_driver atp_driver = {
|
static struct usb_driver atp_driver = {
|
||||||
.name = "appletouch",
|
.name = "appletouch",
|
||||||
.probe = atp_probe,
|
.probe = atp_probe,
|
||||||
.disconnect = atp_disconnect,
|
.disconnect = atp_disconnect,
|
||||||
.suspend = atp_suspend,
|
.suspend = atp_suspend,
|
||||||
.resume = atp_resume,
|
.resume = atp_resume,
|
||||||
|
.reset_resume = atp_reset_resume,
|
||||||
.id_table = atp_table,
|
.id_table = atp_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,6 +47,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||||||
/* Edirol SD-20 */
|
/* Edirol SD-20 */
|
||||||
{ USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME },
|
{ USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||||
|
|
||||||
|
/* appletouch */
|
||||||
|
{ USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||||
|
|
||||||
/* M-Systems Flash Disk Pioneers */
|
/* M-Systems Flash Disk Pioneers */
|
||||||
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
|
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user