Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 62175
b: refs/heads/master
c: 5a6eb67
h: refs/heads/master
i:
  62173: c658dd2
  62171: 4098988
  62167: cb0b22d
  62159: 58af992
  62143: 38b0304
v: v3
  • Loading branch information
Soeren Sonnenburg authored and Dmitry Torokhov committed Jul 20, 2007
1 parent 452f57e commit 7a1d3b1
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 38 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e6b20d8d62d87451f41365945b27202d7dadaee6
refs/heads/master: 5a6eb676d3bc4d7a6feab200a92437b62ad298da
111 changes: 74 additions & 37 deletions trunk/drivers/input/mouse/appletouch.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ struct atp {
int xy_acc[ATP_XSENSORS + ATP_YSENSORS];
int overflowwarn; /* overflow warning printed? */
int datalen; /* size of an USB urb transfer */
int idlecount; /* number of empty packets */
struct work_struct work;
};

#define dbg_dump(msg, tab) \
Expand Down Expand Up @@ -208,6 +210,55 @@ static inline int atp_is_geyser_3(struct atp *dev)
(productId == GEYSER4_JIS_PRODUCT_ID);
}

/*
* By default Geyser 3 device sends standard USB HID mouse
* packets (Report ID 2). This code changes device mode, so it
* sends raw sensor reports (Report ID 5).
*/
static int atp_geyser3_init(struct usb_device *udev)
{
char data[8];
int size;

size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
ATP_GEYSER3_MODE_READ_REQUEST_ID,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
ATP_GEYSER3_MODE_REQUEST_VALUE,
ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);

if (size != 8) {
err("Could not do mode read request from device"
" (Geyser 3 mode)");
return -EIO;
}

/* Apply the mode switch */
data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE;

size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
ATP_GEYSER3_MODE_WRITE_REQUEST_ID,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
ATP_GEYSER3_MODE_REQUEST_VALUE,
ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);

if (size != 8) {
err("Could not do mode write request to device"
" (Geyser 3 mode)");
return -EIO;
}
return 0;
}

/* Reinitialise the device if it's a geyser 3 */
static void atp_reinit(struct work_struct *work)
{
struct atp *dev = container_of(work, struct atp, work);
struct usb_device *udev = dev->udev;

dev->idlecount = 0;
atp_geyser3_init(udev);
}

static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
int *z, int *fingers)
{
Expand Down Expand Up @@ -439,8 +490,8 @@ static void atp_complete(struct urb* urb)
}
dev->x_old = x;
dev->y_old = y;
}
else if (!x && !y) {

} else if (!x && !y) {

dev->x_old = dev->y_old = -1;
input_report_key(dev->input, BTN_TOUCH, 0);
Expand All @@ -449,11 +500,21 @@ static void atp_complete(struct urb* urb)

/* reset the accumulator on release */
memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
}

input_report_key(dev->input, BTN_LEFT,
!!dev->data[dev->datalen - 1]);
/* Geyser 3 will continue to send packets continually after
the first touch unless reinitialised. Do so if it's been
idle for a while in order to avoid waking the kernel up
several hundred times a second */
if (atp_is_geyser_3(dev)) {
dev->idlecount++;
if (dev->idlecount == 10) {
dev->valid = 0;
schedule_work(&dev->work);
}
}
}

input_report_key(dev->input, BTN_LEFT, dev->data[dev->datalen - 1] & 1);
input_sync(dev->input);

exit:
Expand All @@ -480,6 +541,7 @@ static void atp_close(struct input_dev *input)
struct atp *dev = input_get_drvdata(input);

usb_kill_urb(dev->urb);
cancel_work_sync(&dev->work);
dev->open = 0;
}

Expand Down Expand Up @@ -528,40 +590,10 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
dev->datalen = 81;

if (atp_is_geyser_3(dev)) {
/*
* By default Geyser 3 device sends standard USB HID mouse
* packets (Report ID 2). This code changes device mode, so it
* sends raw sensor reports (Report ID 5).
*/
char data[8];
int size;

size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
ATP_GEYSER3_MODE_READ_REQUEST_ID,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
ATP_GEYSER3_MODE_REQUEST_VALUE,
ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);

if (size != 8) {
err("Could not do mode read request from device"
" (Geyser 3 mode)");
/* switch to raw sensor mode */
if (atp_geyser3_init(udev))
goto err_free_devs;
}

/* Apply the mode switch */
data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE;

size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
ATP_GEYSER3_MODE_WRITE_REQUEST_ID,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
ATP_GEYSER3_MODE_REQUEST_VALUE,
ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);

if (size != 8) {
err("Could not do mode write request to device"
" (Geyser 3 mode)");
goto err_free_devs;
}
printk("appletouch Geyser 3 inited.\n");
}

Expand Down Expand Up @@ -636,6 +668,8 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
/* save our data pointer in this interface device */
usb_set_intfdata(iface, dev);

INIT_WORK(&dev->work, atp_reinit);

return 0;

err_free_buffer:
Expand Down Expand Up @@ -669,14 +703,17 @@ static void atp_disconnect(struct usb_interface *iface)
static int atp_suspend(struct usb_interface *iface, pm_message_t message)
{
struct atp *dev = usb_get_intfdata(iface);

usb_kill_urb(dev->urb);
dev->valid = 0;

return 0;
}

static int atp_resume(struct usb_interface *iface)
{
struct atp *dev = usb_get_intfdata(iface);

if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC))
return -EIO;

Expand Down

0 comments on commit 7a1d3b1

Please sign in to comment.