@@ -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
};