|
@@ -68,6 +68,287 @@ struct ntrig_data {
|
|
|
__u16 sensor_physical_height;
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+static ssize_t show_phys_width(struct device *dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
|
|
+ struct ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ return sprintf(buf, "%d\n", nd->sensor_physical_width);
|
|
|
+}
|
|
|
+
|
|
|
+static DEVICE_ATTR(sensor_physical_width, S_IRUGO, show_phys_width, NULL);
|
|
|
+
|
|
|
+static ssize_t show_phys_height(struct device *dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
|
|
+ struct ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ return sprintf(buf, "%d\n", nd->sensor_physical_height);
|
|
|
+}
|
|
|
+
|
|
|
+static DEVICE_ATTR(sensor_physical_height, S_IRUGO, show_phys_height, NULL);
|
|
|
+
|
|
|
+static ssize_t show_log_width(struct device *dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
|
|
+ struct ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ return sprintf(buf, "%d\n", nd->sensor_logical_width);
|
|
|
+}
|
|
|
+
|
|
|
+static DEVICE_ATTR(sensor_logical_width, S_IRUGO, show_log_width, NULL);
|
|
|
+
|
|
|
+static ssize_t show_log_height(struct device *dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
|
|
+ struct ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ return sprintf(buf, "%d\n", nd->sensor_logical_height);
|
|
|
+}
|
|
|
+
|
|
|
+static DEVICE_ATTR(sensor_logical_height, S_IRUGO, show_log_height, NULL);
|
|
|
+
|
|
|
+static ssize_t show_min_width(struct device *dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
|
|
+ struct ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ return sprintf(buf, "%d\n", nd->min_width *
|
|
|
+ nd->sensor_physical_width /
|
|
|
+ nd->sensor_logical_width);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t set_min_width(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 ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ unsigned long val;
|
|
|
+
|
|
|
+ if (strict_strtoul(buf, 0, &val))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (val > nd->sensor_physical_width)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ nd->min_width = val * nd->sensor_logical_width /
|
|
|
+ nd->sensor_physical_width;
|
|
|
+
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+static DEVICE_ATTR(min_width, S_IWUSR | S_IRUGO, show_min_width, set_min_width);
|
|
|
+
|
|
|
+static ssize_t show_min_height(struct device *dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
|
|
+ struct ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ return sprintf(buf, "%d\n", nd->min_height *
|
|
|
+ nd->sensor_physical_height /
|
|
|
+ nd->sensor_logical_height);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t set_min_height(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 ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ unsigned long val;
|
|
|
+
|
|
|
+ if (strict_strtoul(buf, 0, &val))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (val > nd->sensor_physical_height)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ nd->min_height = val * nd->sensor_logical_height /
|
|
|
+ nd->sensor_physical_height;
|
|
|
+
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+static DEVICE_ATTR(min_height, S_IWUSR | S_IRUGO, show_min_height,
|
|
|
+ set_min_height);
|
|
|
+
|
|
|
+static ssize_t show_activate_slack(struct device *dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
|
|
+ struct ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ return sprintf(buf, "%d\n", nd->activate_slack);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t set_activate_slack(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 ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ unsigned long val;
|
|
|
+
|
|
|
+ if (strict_strtoul(buf, 0, &val))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (val > 0x7f)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ nd->activate_slack = val;
|
|
|
+
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+static DEVICE_ATTR(activate_slack, S_IWUSR | S_IRUGO, show_activate_slack,
|
|
|
+ set_activate_slack);
|
|
|
+
|
|
|
+static ssize_t show_activation_width(struct device *dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
|
|
+ struct ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ return sprintf(buf, "%d\n", nd->activation_width *
|
|
|
+ nd->sensor_physical_width /
|
|
|
+ nd->sensor_logical_width);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t set_activation_width(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 ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ unsigned long val;
|
|
|
+
|
|
|
+ if (strict_strtoul(buf, 0, &val))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (val > nd->sensor_physical_width)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ nd->activation_width = val * nd->sensor_logical_width /
|
|
|
+ nd->sensor_physical_width;
|
|
|
+
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+static DEVICE_ATTR(activation_width, S_IWUSR | S_IRUGO, show_activation_width,
|
|
|
+ set_activation_width);
|
|
|
+
|
|
|
+static ssize_t show_activation_height(struct device *dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
|
|
+ struct ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ return sprintf(buf, "%d\n", nd->activation_height *
|
|
|
+ nd->sensor_physical_height /
|
|
|
+ nd->sensor_logical_height);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t set_activation_height(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 ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ unsigned long val;
|
|
|
+
|
|
|
+ if (strict_strtoul(buf, 0, &val))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (val > nd->sensor_physical_height)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ nd->activation_height = val * nd->sensor_logical_height /
|
|
|
+ nd->sensor_physical_height;
|
|
|
+
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+static DEVICE_ATTR(activation_height, S_IWUSR | S_IRUGO,
|
|
|
+ show_activation_height, set_activation_height);
|
|
|
+
|
|
|
+static ssize_t show_deactivate_slack(struct device *dev,
|
|
|
+ struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
|
|
+ struct ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ return sprintf(buf, "%d\n", -nd->deactivate_slack);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t set_deactivate_slack(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 ntrig_data *nd = hid_get_drvdata(hdev);
|
|
|
+
|
|
|
+ unsigned long val;
|
|
|
+
|
|
|
+ if (strict_strtoul(buf, 0, &val))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * No more than 8 terminal frames have been observed so far
|
|
|
+ * and higher slack is highly likely to leave the single
|
|
|
+ * touch emulation stuck down.
|
|
|
+ */
|
|
|
+ if (val > 7)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ nd->deactivate_slack = -val;
|
|
|
+
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+static DEVICE_ATTR(deactivate_slack, S_IWUSR | S_IRUGO, show_deactivate_slack,
|
|
|
+ set_deactivate_slack);
|
|
|
+
|
|
|
+static struct attribute *sysfs_attrs[] = {
|
|
|
+ &dev_attr_sensor_physical_width.attr,
|
|
|
+ &dev_attr_sensor_physical_height.attr,
|
|
|
+ &dev_attr_sensor_logical_width.attr,
|
|
|
+ &dev_attr_sensor_logical_height.attr,
|
|
|
+ &dev_attr_min_height.attr,
|
|
|
+ &dev_attr_min_width.attr,
|
|
|
+ &dev_attr_activate_slack.attr,
|
|
|
+ &dev_attr_activation_width.attr,
|
|
|
+ &dev_attr_activation_height.attr,
|
|
|
+ &dev_attr_deactivate_slack.attr,
|
|
|
+ NULL
|
|
|
+};
|
|
|
+
|
|
|
+static struct attribute_group ntrig_attribute_group = {
|
|
|
+ .attrs = sysfs_attrs
|
|
|
+};
|
|
|
+
|
|
|
/*
|
|
|
* this driver is aimed at two firmware versions in circulation:
|
|
|
* - dual pen/finger single touch
|
|
@@ -546,6 +827,8 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|
|
if (report)
|
|
|
usbhid_submit_report(hdev, report, USB_DIR_OUT);
|
|
|
|
|
|
+ ret = sysfs_create_group(&hdev->dev.kobj,
|
|
|
+ &ntrig_attribute_group);
|
|
|
|
|
|
return 0;
|
|
|
err_free:
|
|
@@ -555,6 +838,8 @@ err_free:
|
|
|
|
|
|
static void ntrig_remove(struct hid_device *hdev)
|
|
|
{
|
|
|
+ sysfs_remove_group(&hdev->dev.kobj,
|
|
|
+ &ntrig_attribute_group);
|
|
|
hid_hw_stop(hdev);
|
|
|
kfree(hid_get_drvdata(hdev));
|
|
|
}
|