wacom_sys.c 11.0 KB
Newer Older
1
/*
2
 * drivers/input/tablet/wacom_sys.c
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
 *
 *  USB Wacom Graphire and Wacom Intuos tablet support - system specific code
 */

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include "wacom.h"
#include "wacom_wac.h"

#define USB_REQ_GET_REPORT	0x01
#define USB_REQ_SET_REPORT	0x09

static int usb_get_report(struct usb_interface *intf, unsigned char type,
				unsigned char id, void *buf, int size)
{
	return usb_control_msg(interface_to_usbdev(intf),
		usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
		USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
		(type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
		buf, size, 100);
}

static int usb_set_report(struct usb_interface *intf, unsigned char type,
				unsigned char id, void *buf, int size)
{
	return usb_control_msg(interface_to_usbdev(intf),
		usb_sndctrlpipe(interface_to_usbdev(intf), 0),
                USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
		buf, size, 1000);
}

static struct input_dev * get_input_dev(struct wacom_combo *wcombo)
{
	return wcombo->wacom->dev;
}

45
static void wacom_sys_irq(struct urb *urb)
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
{
	struct wacom *wacom = urb->context;
	struct wacom_combo wcombo;
	int retval;

	switch (urb->status) {
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
		return;
	default:
		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
		goto exit;
	}

	wcombo.wacom = wacom;
	wcombo.urb = urb;

	if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo))
		input_sync(get_input_dev(&wcombo));

 exit:
73
	usb_mark_last_busy(wacom->usbdev);
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
	retval = usb_submit_urb (urb, GFP_ATOMIC);
	if (retval)
		err ("%s - usb_submit_urb failed with result %d",
		     __FUNCTION__, retval);
}

void wacom_report_key(void *wcombo, unsigned int key_type, int key_data)
{
	input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data);
	return;
}

void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data)
{
	input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data);
	return;
}

void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data)
{
	input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data);
	return;
}

void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value)
{
	input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value);
	return;
}

__u16 wacom_be16_to_cpu(unsigned char *data)
{
	__u16 value;
	value = be16_to_cpu(*(__be16 *) data);
	return value;
}

__u16 wacom_le16_to_cpu(unsigned char *data)
{
	__u16 value;
P
Ping Cheng 已提交
114
	value = le16_to_cpu(*(__le16 *) data);
115 116 117 118 119 120 121 122 123 124 125
	return value;
}

void wacom_input_sync(void *wcombo)
{
	input_sync(get_input_dev((struct wacom_combo *)wcombo));
	return;
}

static int wacom_open(struct input_dev *dev)
{
126
	struct wacom *wacom = input_get_drvdata(dev);
127

128 129
	mutex_lock(&wacom->lock);

130
	wacom->irq->dev = wacom->usbdev;
131 132 133

	if (usb_autopm_get_interface(wacom->intf) < 0) {
		mutex_unlock(&wacom->lock);
134
		return -EIO;
135 136 137 138 139 140 141 142 143 144
	}

	if (usb_submit_urb(wacom->irq, GFP_KERNEL)) {
		usb_autopm_put_interface(wacom->intf);
		mutex_unlock(&wacom->lock);
		return -EIO;
	}

	wacom->open = 1;
	wacom->intf->needs_remote_wakeup = 1;
145

146
	mutex_unlock(&wacom->lock);
147 148 149 150 151
	return 0;
}

static void wacom_close(struct input_dev *dev)
{
152
	struct wacom *wacom = input_get_drvdata(dev);
153

154
	mutex_lock(&wacom->lock);
155
	usb_kill_urb(wacom->irq);
156 157 158
	wacom->open = 0;
	wacom->intf->needs_remote_wakeup = 0;
	mutex_unlock(&wacom->lock);
159 160
}

161 162
void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
163 164
	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_1) |
		BIT_MASK(BTN_5);
165 166 167
	input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
}

168 169
void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
170 171 172 173 174
	input_dev->evbit[0] |= BIT_MASK(EV_MSC);
	input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER);
	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) |
		BIT_MASK(BTN_4);
175 176 177 178
}

void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
179 180 181 182 183 184
	input_dev->evbit[0] |= BIT_MASK(EV_REL);
	input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
		BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2);
185 186 187
	input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
}

P
Ping Cheng 已提交
188
void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
189
{
190 191 192
	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER);
	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) |
		BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3);
P
Ping Cheng 已提交
193
	input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
194
	input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
P
Ping Cheng 已提交
195 196 197 198
}

void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
199 200
	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_4) |
		BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7);
P
Ping Cheng 已提交
201
	input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
202 203
}

204 205 206 207 208
void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9);
}

209 210
void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
211 212 213 214 215 216 217 218 219 220
	input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL);
	input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
	input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) |
		BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
		BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) |
		BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) |
		BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2);
221 222 223 224 225 226 227 228 229 230
	input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
	input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
	input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
	input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
	input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
	input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
}

void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
231 232
	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2) |
		BIT_MASK(BTN_TOOL_RUBBER);
233 234 235 236
}

void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
237
	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER);
238 239 240 241 242 243 244 245 246
}

static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	struct usb_endpoint_descriptor *endpoint;
	struct wacom *wacom;
	struct wacom_wac *wacom_wac;
	struct input_dev *input_dev;
247
	int error = -ENOMEM;
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
	char rep_data[2], limit = 0;

	wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
	wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!wacom || !input_dev || !wacom_wac)
		goto fail1;

	wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma);
	if (!wacom_wac->data)
		goto fail1;

	wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
	if (!wacom->irq)
		goto fail2;

	wacom->usbdev = dev;
	wacom->dev = input_dev;
266 267
	wacom->intf = intf;
	mutex_init(&wacom->lock);
268 269 270 271
	usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
	strlcat(wacom->phys, "/input0", sizeof(wacom->phys));

	wacom_wac->features = get_wacom_feature(id);
272
	BUG_ON(wacom_wac->features->pktlen > 10);
273 274 275 276 277

	input_dev->name = wacom_wac->features->name;
	wacom->wacom_wac = wacom_wac;
	usb_to_input_id(dev, &input_dev->id);

278
	input_dev->dev.parent = &intf->dev;
279 280 281

	input_set_drvdata(input_dev, wacom);

282 283 284
	input_dev->open = wacom_open;
	input_dev->close = wacom_close;

285 286 287
	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
		BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS);
288 289 290
	input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0);
	input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0);
	input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0);
291
	input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
292 293 294 295 296 297 298 299

	wacom_init_input_dev(input_dev, wacom_wac);

	endpoint = &intf->cur_altsetting->endpoint[0].desc;

	usb_fill_int_urb(wacom->irq, dev,
			 usb_rcvintpipe(dev, endpoint->bEndpointAddress),
			 wacom_wac->data, wacom_wac->features->pktlen,
P
Ping Cheng 已提交
300
			 wacom_sys_irq, wacom, endpoint->bInterval);
301 302 303
	wacom->irq->transfer_dma = wacom->data_dma;
	wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

304 305 306
	error = input_register_device(wacom->dev);
	if (error)
		goto fail3;
307 308 309 310 311 312 313 314 315 316 317 318

	/* Ask the tablet to report tablet data. Repeat until it succeeds */
	do {
		rep_data[0] = 2;
		rep_data[1] = 2;
		usb_set_report(intf, 3, 2, rep_data, 2);
		usb_get_report(intf, 3, 2, rep_data, 2);
	} while (rep_data[1] != 2 && limit++ < 5);

	usb_set_intfdata(intf, wacom);
	return 0;

319 320 321
 fail3:	usb_free_urb(wacom->irq);
 fail2:	usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma);
 fail1:	input_free_device(input_dev);
322 323
	kfree(wacom);
	kfree(wacom_wac);
324
	return error;
325 326 327 328
}

static void wacom_disconnect(struct usb_interface *intf)
{
329
	struct wacom *wacom = usb_get_intfdata(intf);
330 331

	usb_set_intfdata(intf, NULL);
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369

	usb_kill_urb(wacom->irq);
	input_unregister_device(wacom->dev);
	usb_free_urb(wacom->irq);
	usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma);
	kfree(wacom->wacom_wac);
	kfree(wacom);
}

static int wacom_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct wacom *wacom = usb_get_intfdata(intf);

	mutex_lock(&wacom->lock);
	usb_kill_urb(wacom->irq);
	mutex_unlock(&wacom->lock);

	return 0;
}

static int wacom_resume(struct usb_interface *intf)
{
	struct wacom *wacom = usb_get_intfdata(intf);
	int rv;

	mutex_lock(&wacom->lock);
	if (wacom->open)
		rv = usb_submit_urb(wacom->irq, GFP_NOIO);
	else
		rv = 0;
	mutex_unlock(&wacom->lock);

	return rv;
}

static int wacom_reset_resume(struct usb_interface *intf)
{
	return wacom_resume(intf);
370 371 372 373 374 375
}

static struct usb_driver wacom_driver = {
	.name =		"wacom",
	.probe =	wacom_probe,
	.disconnect =	wacom_disconnect,
376 377 378 379
	.suspend =	wacom_suspend,
	.resume =	wacom_resume,
	.reset_resume =	wacom_reset_resume,
	.supports_autosuspend = 1,
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
};

static int __init wacom_init(void)
{
	int result;
	wacom_driver.id_table = get_device_table();
	result = usb_register(&wacom_driver);
	if (result == 0)
		info(DRIVER_VERSION ":" DRIVER_DESC);
	return result;
}

static void __exit wacom_exit(void)
{
	usb_deregister(&wacom_driver);
}

module_init(wacom_init);
module_exit(wacom_exit);