Hi,
Please comment, test, ack, sign-off and so on.
More features are on the way, but I want to start with very basic
version of the driver to test interaction with connecting/disconnecting
USB cable, speed issues (my PC with bluetooth dongle 3.0 is not fast
enough for smooth work).
There are 3 warnings for the patch generated by checkpatch.pl. One looks
like a false positive, the rest are about line over 80 characters, but I
belive it's justified.
Ping, thanks again for all the help that I received for you!
--
Kind regards,
Przemo Firszt
>From b29dabf3d7951b84fd224355fc76e80bca221640 Mon Sep 17 00:00:00 2001
From: Przemo Firszt <[email protected]>
Date: Sun, 28 Aug 2011 20:35:30 +0100
Subject: [PATCH] Initial driver for Wacom Intuos4 Wireless (Bluetooth)
This is very basic driver for Wacom Intuos4 Wireless tablet. It supports only
position, pressure and tip button of pen and eraser. More features will be
added in future releases.
Signed-off-by: Przemo Firszt <[email protected]>
---
drivers/hid/Kconfig | 6 +
drivers/hid/Makefile | 1 +
drivers/hid/hid-core.c | 1 +
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-wacom-i4wl.c | 240 ++++++++++++++++++++++++++++++++++++++++++
5 files changed, 249 insertions(+), 0 deletions(-)
create mode 100644 drivers/hid/hid-wacom-i4wl.c
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 1130a89..abb69df 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -586,6 +586,12 @@ config HID_WACOM_POWER_SUPPLY
Say Y here if you want to enable power supply status monitoring for
Wacom Bluetooth devices.
+config HID_WACOM_I4WL
+ tristate "Wacom Intuos4 Bluetooth devices support"
+ depends on BT_HIDP
+ ---help---
+ Say Y here if you have Wacom Intuos4 Bluetooth (Wireless) tablet.
+
config HID_WIIMOTE
tristate "Nintendo Wii Remote support"
depends on BT_HIDP
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 0a0a38e..3049c8b 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o
obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o
obj-$(CONFIG_HID_WACOM) += hid-wacom.o
+obj-$(CONFIG_HID_WACOM_I4WL) += hid-wacom-i4wl.o
obj-$(CONFIG_HID_WALTOP) += hid-waltop.o
obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 242353d..29bf4ae 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1502,6 +1502,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 7484e1b..b8ec5be 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -660,6 +660,7 @@
#define USB_VENDOR_ID_WACOM 0x056a
#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
+#define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0x00BD
#define USB_VENDOR_ID_WALTOP 0x172f
#define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH 0x0032
diff --git a/drivers/hid/hid-wacom-i4wl.c b/drivers/hid/hid-wacom-i4wl.c
new file mode 100644
index 0000000..770e168
--- /dev/null
+++ b/drivers/hid/hid-wacom-i4wl.c
@@ -0,0 +1,240 @@
+/*
+ * Intuos4 Wireless Wacom Tablet support
+ *
+ * Copyright (c) 2011 Przemyslaw Firszt
+ */
+
+/*
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "hid-ids.h"
+
+struct wacom_i4wl_data {
+ __u8 features;
+ __u16 tool;
+};
+
+static void wacom_i4wl_set_features(struct hid_device *hdev)
+{
+ int ret;
+ __u8 rep_data[2];
+
+ /*set high speed, tablet mode*/
+ rep_data[0] = 0x03;
+ rep_data[1] = 0x00;
+ ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
+ HID_FEATURE_REPORT);
+ return;
+}
+
+static void wacom_i4wl_parse_pen_report(struct wacom_i4wl_data *wdata,
+ struct input_dev *input, unsigned char *data)
+{
+ __u16 x, y, pressure;
+ __u32 id;
+
+ switch (data[1]) {
+ case 0x80: /* Out of proximity report */
+ wdata->tool = 0;
+ input_report_key(input, BTN_TOUCH, 0);
+ input_report_abs(input, ABS_PRESSURE, 0);
+ input_report_key(input, wdata->tool, 0);
+ input_sync(input);
+ break;
+ case 0xC2: /* Tool report */
+ id = ((data[2] << 4) | (data[3] >> 4) |
+ ((data[7] & 0x0f) << 20) |
+ ((data[8] & 0xf0) << 12)) & 0xfffff;
+
+ switch (id) {
+ case 0x802:
+ wdata->tool = BTN_TOOL_PEN;
+ break;
+ case 0x80A:
+ wdata->tool = BTN_TOOL_RUBBER;
+ break;
+ }
+ break;
+ default: /* Position/pressure report */
+ x = data[2] << 9 | data[3] << 1 | ((data[9] & 0x02) >> 1);
+ y = data[4] << 9 | data[5] << 1 | (data[9] & 0x01);
+ pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5)
+ | (data[1] & 0x01);
+
+ if (pressure > 1)
+ input_report_key(input, BTN_TOUCH, 1);
+ else
+ input_report_key(input, BTN_TOUCH, 0);
+
+ input_report_key(input, wdata->tool, 1);
+ input_report_abs(input, ABS_X, x);
+ input_report_abs(input, ABS_Y, y);
+ input_report_abs(input, ABS_PRESSURE, pressure);
+ input_sync(input);
+
+ break;
+ }
+
+ return;
+}
+
+static int wacom_i4wl_raw_event(struct hid_device *hdev,
+ struct hid_report *report, u8 *raw_data, int size)
+{
+ struct wacom_i4wl_data *wdata = hid_get_drvdata(hdev);
+ struct hid_input *hidinput;
+ struct input_dev *input;
+ unsigned char *data = (unsigned char *) raw_data;
+ __u8 report_id;
+ int subreports, i, offset;
+
+ if (!(hdev->claimed & HID_CLAIMED_INPUT))
+ return 0;
+
+ hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
+ input = hidinput->input;
+
+ switch (data[0]) {
+ case 0x03:
+ subreports = 2;
+ break;
+ case 0x04:
+ subreports = 3;
+ break;
+ default:
+ hid_err(hdev, "Unknown report: %d,%d size:%d\n",
+ data[0], data[1], size);
+ return 0;
+ break;
+ }
+
+ i = 0;
+ do {
+ offset = (i * 10) + 1;
+ report_id = data[offset];
+
+ switch (data[offset]) {
+ case 0x00: /* Empty report */
+ break;
+ case 0x02: /* Pen report */
+ wacom_i4wl_parse_pen_report(wdata, input, data+offset);
+ break;
+ case 0x03: /* Features Report */
+ wdata->features = data[2];
+ break;
+ case 0x0C: /* Button report */
+ break;
+ default:
+ hid_err(hdev, "Unknown report: %d,%d size:%d\n",
+ data[0], data[1], size);
+ break;
+ }
+ i++;
+ } while (i < subreports);
+ return 1;
+}
+
+static int wacom_i4wl_probe(struct hid_device *hdev,
+ const struct hid_device_id *id)
+{
+ struct hid_input *hidinput;
+ struct input_dev *input;
+ struct wacom_i4wl_data *wdata;
+ int ret;
+
+ wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
+
+ if (wdata == NULL) {
+ hid_err(hdev, "can't alloc wacom_i4wl descriptor\n");
+ return -ENOMEM;
+ }
+
+ wdata->features = 0;
+ hid_set_drvdata(hdev, wdata);
+ ret = hid_parse(hdev);
+
+ if (ret) {
+ hid_err(hdev, "parse failed\n");
+ goto err_free;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (ret) {
+ hid_err(hdev, "hw start failed\n");
+ goto err_free;
+ }
+
+ wacom_i4wl_set_features(hdev);
+
+ hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
+ input = hidinput->input;
+
+ input->evbit[0] |= BIT(EV_ABS) | BIT(EV_KEY);
+
+ __set_bit(BTN_TOOL_PEN, input->keybit);
+ __set_bit(BTN_TOOL_RUBBER, input->keybit);
+ __set_bit(BTN_TOUCH, input->keybit);
+
+ input_set_abs_params(input, ABS_X, 0, 40640, 4, 0);
+ input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0);
+ input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0);
+
+ return 0;
+
+err_free:
+ kfree(wdata);
+ return ret;
+
+}
+
+static void wacom_i4wl_remove(struct hid_device *hdev)
+{
+ hid_hw_stop(hdev);
+ kfree(hid_get_drvdata(hdev));
+}
+
+static const struct hid_device_id wacom_i4wl_devices[] = {
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
+
+ { }
+};
+MODULE_DEVICE_TABLE(hid, wacom_i4wl_devices);
+
+static struct hid_driver wacom_i4wl_driver = {
+ .name = "wacom_i4wl",
+ .id_table = wacom_i4wl_devices,
+ .probe = wacom_i4wl_probe,
+ .remove = wacom_i4wl_remove,
+ .raw_event = wacom_i4wl_raw_event,
+};
+
+static int __init wacom_i4wl_init(void)
+{
+ int ret;
+
+ ret = hid_register_driver(&wacom_i4wl_driver);
+ if (ret)
+ pr_err("can't register wacom_i4wl driver\n");
+
+ return ret;
+}
+
+static void __exit wacom_i4wl_exit(void)
+{
+ hid_unregister_driver(&wacom_i4wl_driver);
+}
+
+module_init(wacom_i4wl_init);
+module_exit(wacom_i4wl_exit);
+MODULE_LICENSE("GPL");
--
1.7.6
------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security
threats, fraudulent activity, and more. Splunk takes this data and makes
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2dcopy2
_______________________________________________
Linuxwacom-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel