Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 193507
b: refs/heads/master
c: 4492eff
h: refs/heads/master
i:
  193505: 171a8d4
  193503: fbd9009
v: v3
  • Loading branch information
Ping Cheng authored and Dmitry Torokhov committed Apr 14, 2010
1 parent 2ffb01e commit 88614e5
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 23 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: 3b57ca0f80c5c8994b5b1e3d3f904cfe727951f2
refs/heads/master: 4492efffffeb88d87e7aa74765f3c53b3a7dd40f
83 changes: 82 additions & 1 deletion trunk/drivers/input/tablet/wacom_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,81 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
return error;
}

struct wacom_usbdev_data {
struct list_head list;
struct kref kref;
struct usb_device *dev;
struct wacom_shared shared;
};

static LIST_HEAD(wacom_udev_list);
static DEFINE_MUTEX(wacom_udev_list_lock);

static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev)
{
struct wacom_usbdev_data *data;

list_for_each_entry(data, &wacom_udev_list, list) {
if (data->dev == dev) {
kref_get(&data->kref);
return data;
}
}

return NULL;
}

static int wacom_add_shared_data(struct wacom_wac *wacom,
struct usb_device *dev)
{
struct wacom_usbdev_data *data;
int retval = 0;

mutex_lock(&wacom_udev_list_lock);

data = wacom_get_usbdev_data(dev);
if (!data) {
data = kzalloc(sizeof(struct wacom_usbdev_data), GFP_KERNEL);
if (!data) {
retval = -ENOMEM;
goto out;
}

kref_init(&data->kref);
data->dev = dev;
list_add_tail(&data->list, &wacom_udev_list);
}

wacom->shared = &data->shared;

out:
mutex_unlock(&wacom_udev_list_lock);
return retval;
}

static void wacom_release_shared_data(struct kref *kref)
{
struct wacom_usbdev_data *data =
container_of(kref, struct wacom_usbdev_data, kref);

mutex_lock(&wacom_udev_list_lock);
list_del(&data->list);
mutex_unlock(&wacom_udev_list_lock);

kfree(data);
}

static void wacom_remove_shared_data(struct wacom_wac *wacom)
{
struct wacom_usbdev_data *data;

if (wacom->shared) {
data = container_of(wacom->shared, struct wacom_usbdev_data, shared);
kref_put(&data->kref, wacom_release_shared_data);
wacom->shared = NULL;
}
}

static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
Expand Down Expand Up @@ -600,6 +675,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
features->device_type == BTN_TOOL_PEN ?
" Pen" : " Finger",
sizeof(wacom_wac->name));

error = wacom_add_shared_data(wacom_wac, dev);
if (error)
goto fail3;
}

input_dev->name = wacom_wac->name;
Expand All @@ -624,14 +703,15 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i

error = input_register_device(wacom->dev);
if (error)
goto fail3;
goto fail4;

/* Note that if query fails it is not a hard failure */
wacom_query_tablet_data(intf, features);

usb_set_intfdata(intf, wacom);
return 0;

fail4: wacom_remove_shared_data(wacom_wac);
fail3: usb_free_urb(wacom->irq);
fail2: usb_buffer_free(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma);
fail1: input_free_device(input_dev);
Expand All @@ -651,6 +731,7 @@ static void wacom_disconnect(struct usb_interface *intf)
usb_free_urb(wacom->irq);
usb_buffer_free(interface_to_usbdev(intf), WACOM_PKGLEN_MAX,
wacom->wacom_wac->data, wacom->data_dma);
wacom_remove_shared_data(wacom->wacom_wac);
kfree(wacom->wacom_wac);
kfree(wacom);
}
Expand Down
33 changes: 12 additions & 21 deletions trunk/drivers/input/tablet/wacom_wac.c
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,6 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
struct wacom_features *features = &wacom->features;
char *data = wacom->data;
int prox = 0, pressure, idx = -1;
static int stylusInProx, touchInProx = 1, touchOut;
struct urb *urb = ((struct wacom_combo *)wcombo)->urb;

dbg("wacom_tpc_irq: received report #%d", data[0]);
Expand All @@ -707,16 +706,12 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
prox = data[1] & 0x03;
}

if (!stylusInProx) { /* stylus not in prox */
if (!wacom->shared->stylus_in_proximity) {
if (prox) {
if (touchInProx) {
wacom_tpc_touch_in(wacom, wcombo);
touchOut = 1;
return 1;
}
wacom_tpc_touch_in(wacom, wcombo);
} else {
/* 2FGT out-prox */
if (data[0] == WACOM_REPORT_TPC2FG) {
/* 2FGT out-prox */
idx = (wacom->id[1] & 0x01) - 1;
if (idx == 0) {
wacom_tpc_touch_out(wacom, wcombo, idx);
Expand All @@ -727,30 +722,28 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
idx = (wacom->id[1] & 0x02) - 1;
if (idx == 1)
wacom_tpc_touch_out(wacom, wcombo, idx);
} else /* one finger touch */
} else {
/* one finger touch */
wacom_tpc_touch_out(wacom, wcombo, 0);
touchOut = 0;
touchInProx = 1;
return 1;
}
wacom->id[0] = 0;
}
} else if (touchOut || !prox) { /* force touch out-prox */
} else if (wacom->id[0]) { /* force touch out-prox */
wacom_tpc_touch_out(wacom, wcombo, 0);
touchOut = 0;
touchInProx = 1;
return 1;
}
return 1;
} else if (data[0] == WACOM_REPORT_PENABLED) { /* Penabled */
prox = data[1] & 0x20;

touchInProx = 0;

if (!wacom->id[0]) { /* first in prox */
/* Going into proximity select tool */
wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
if (wacom->tool[0] == BTN_TOOL_PEN)
wacom->id[0] = STYLUS_DEVICE_ID;
else
wacom->id[0] = ERASER_DEVICE_ID;

wacom->shared->stylus_in_proximity = true;
}
wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
Expand All @@ -763,12 +756,10 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
if (!prox) { /* out-prox */
wacom->id[0] = 0;
/* pen is out so touch can be enabled now */
touchInProx = 1;
wacom->shared->stylus_in_proximity = false;
}
wacom_report_key(wcombo, wacom->tool[0], prox);
wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
stylusInProx = prox;
return 1;
}
return 0;
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/input/tablet/wacom_wac.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,18 @@ struct wacom_features {
unsigned char unitExpo;
};

struct wacom_shared {
bool stylus_in_proximity;
};

struct wacom_wac {
char name[64];
unsigned char *data;
int tool[2];
int id[2];
__u32 serial[2];
struct wacom_features features;
struct wacom_shared *shared;
};

#endif

0 comments on commit 88614e5

Please sign in to comment.