diff mbox

[2/2] hid-ntrig: calibration

Message ID 1299829072-19489-2-git-send-email-rafi@seas.upenn.edu (mailing list archive)
State New, archived
Delegated to: Jiri Kosina
Headers show

Commit Message

Rafi Rubin March 11, 2011, 7:37 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index 24ab6a5..ddf2c76 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -490,6 +490,53 @@  static ssize_t store_mode(struct device *dev,
 }
 static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, store_mode);
 
+static ssize_t ntrig_calibrate(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct usb_device *usb_dev = hid_to_usb_dev(hdev);
+	struct usbhid_device *usbhid = hdev->driver_data;
+	int ret;
+	unsigned long t;
+	unsigned char *data;
+
+	if (strict_strtoul(buf, 0, &t))
+		return -EINVAL;
+
+	data = kmalloc(4, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	spin_lock(&usbhid->lock);
+	set_bit(HID_DISCONNECTED, &usbhid->iofl);
+	spin_unlock(&usbhid->lock);
+
+	ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+			      USB_REQ_CLEAR_FEATURE, USB_TYPE_CLASS
+			      | USB_RECIP_INTERFACE | USB_DIR_IN,
+			      0x30b, 1, data, 4, USB_CTRL_GET_TIMEOUT);
+	if (ret < 0)
+		goto fail;
+
+	msleep(t);
+
+	ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+			      USB_REQ_CLEAR_FEATURE, USB_TYPE_CLASS
+			      | USB_RECIP_INTERFACE | USB_DIR_IN,
+			      0x311, 1, data, 4, USB_CTRL_GET_TIMEOUT);
+
+fail:
+	kfree(data);
+	spin_lock(&usbhid->lock);
+	clear_bit(HID_DISCONNECTED, &usbhid->iofl);
+	spin_unlock(&usbhid->lock);
+	schedule_work(&usbhid->reset_work);
+
+	return (ret < 0) ? ret : count;
+}
+static DEVICE_ATTR(calibrate, S_IWUSR, NULL, ntrig_calibrate);
+
 static struct attribute *sysfs_attrs[] = {
 	&dev_attr_sensor_physical_width.attr,
 	&dev_attr_sensor_physical_height.attr,
@@ -502,6 +549,7 @@  static struct attribute *sysfs_attrs[] = {
 	&dev_attr_activation_height.attr,
 	&dev_attr_deactivate_slack.attr,
 	&dev_attr_mode.attr,
+	&dev_attr_calibrate.attr,
 	NULL
 };