|
@@ -564,6 +564,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 (dev->type != ATP_FOUNTAIN) {
|
|
|
|
+ /* 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,
|
|
static int atp_probe(struct usb_interface *iface,
|
|
const struct usb_device_id *id)
|
|
const struct usb_device_id *id)
|
|
{
|
|
{
|
|
@@ -608,14 +623,6 @@ static int atp_probe(struct usb_interface *iface,
|
|
else
|
|
else
|
|
dev->datalen = 64;
|
|
dev->datalen = 64;
|
|
|
|
|
|
- if (dev->type != ATP_FOUNTAIN) {
|
|
|
|
- /* 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;
|
|
@@ -629,6 +636,10 @@ static int atp_probe(struct usb_interface *iface,
|
|
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));
|
|
|
|
|
|
@@ -721,6 +732,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);
|
|
@@ -741,12 +766,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,
|
|
};
|
|
};
|
|
|
|
|