diff options
| author | Rafi Rubin <rafi@seas.upenn.edu> | 2010-05-04 14:20:17 -0400 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2010-05-11 04:45:22 -0400 |
| commit | eab32f5f65574c7484ed883c2245758f5a98878c (patch) | |
| tree | ce8c94b87c2a16467c730742ecc25074b53b7e3f | |
| parent | 369db2a6008e8fc3cf5006fa8aab71bd58adfc1f (diff) | |
HID: ntrig: add sysfs access to filter parameters
This should make it a little more convenient to tweak the filtering
parameters on the fly. Also unlike load-time parameters, this provides
independent tuning for each device conntected.
Signed-off-by: Rafi Rubin <rafi@seas.upenn.edu>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
| -rw-r--r-- | drivers/hid/hid-ntrig.c | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 227d01527c6a..2c08365f3720 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c | |||
| @@ -68,6 +68,287 @@ struct ntrig_data { | |||
| 68 | __u16 sensor_physical_height; | 68 | __u16 sensor_physical_height; |
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | |||
| 72 | static ssize_t show_phys_width(struct device *dev, | ||
| 73 | struct device_attribute *attr, | ||
| 74 | char *buf) | ||
| 75 | { | ||
| 76 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 77 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 78 | |||
| 79 | return sprintf(buf, "%d\n", nd->sensor_physical_width); | ||
| 80 | } | ||
| 81 | |||
| 82 | static DEVICE_ATTR(sensor_physical_width, S_IRUGO, show_phys_width, NULL); | ||
| 83 | |||
| 84 | static ssize_t show_phys_height(struct device *dev, | ||
| 85 | struct device_attribute *attr, | ||
| 86 | char *buf) | ||
| 87 | { | ||
| 88 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 89 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 90 | |||
| 91 | return sprintf(buf, "%d\n", nd->sensor_physical_height); | ||
| 92 | } | ||
| 93 | |||
| 94 | static DEVICE_ATTR(sensor_physical_height, S_IRUGO, show_phys_height, NULL); | ||
| 95 | |||
| 96 | static ssize_t show_log_width(struct device *dev, | ||
| 97 | struct device_attribute *attr, | ||
| 98 | char *buf) | ||
| 99 | { | ||
| 100 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 101 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 102 | |||
| 103 | return sprintf(buf, "%d\n", nd->sensor_logical_width); | ||
| 104 | } | ||
| 105 | |||
| 106 | static DEVICE_ATTR(sensor_logical_width, S_IRUGO, show_log_width, NULL); | ||
| 107 | |||
| 108 | static ssize_t show_log_height(struct device *dev, | ||
| 109 | struct device_attribute *attr, | ||
| 110 | char *buf) | ||
| 111 | { | ||
| 112 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 113 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 114 | |||
| 115 | return sprintf(buf, "%d\n", nd->sensor_logical_height); | ||
| 116 | } | ||
| 117 | |||
| 118 | static DEVICE_ATTR(sensor_logical_height, S_IRUGO, show_log_height, NULL); | ||
| 119 | |||
| 120 | static ssize_t show_min_width(struct device *dev, | ||
| 121 | struct device_attribute *attr, | ||
| 122 | char *buf) | ||
| 123 | { | ||
| 124 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 125 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 126 | |||
| 127 | return sprintf(buf, "%d\n", nd->min_width * | ||
| 128 | nd->sensor_physical_width / | ||
| 129 | nd->sensor_logical_width); | ||
| 130 | } | ||
| 131 | |||
| 132 | static ssize_t set_min_width(struct device *dev, | ||
| 133 | struct device_attribute *attr, | ||
| 134 | const char *buf, size_t count) | ||
| 135 | { | ||
| 136 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 137 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 138 | |||
| 139 | unsigned long val; | ||
| 140 | |||
| 141 | if (strict_strtoul(buf, 0, &val)) | ||
| 142 | return -EINVAL; | ||
| 143 | |||
| 144 | if (val > nd->sensor_physical_width) | ||
| 145 | return -EINVAL; | ||
| 146 | |||
| 147 | nd->min_width = val * nd->sensor_logical_width / | ||
| 148 | nd->sensor_physical_width; | ||
| 149 | |||
| 150 | return count; | ||
| 151 | } | ||
| 152 | |||
| 153 | static DEVICE_ATTR(min_width, S_IWUSR | S_IRUGO, show_min_width, set_min_width); | ||
| 154 | |||
| 155 | static ssize_t show_min_height(struct device *dev, | ||
| 156 | struct device_attribute *attr, | ||
| 157 | char *buf) | ||
| 158 | { | ||
| 159 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 160 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 161 | |||
| 162 | return sprintf(buf, "%d\n", nd->min_height * | ||
| 163 | nd->sensor_physical_height / | ||
| 164 | nd->sensor_logical_height); | ||
| 165 | } | ||
| 166 | |||
| 167 | static ssize_t set_min_height(struct device *dev, | ||
| 168 | struct device_attribute *attr, | ||
| 169 | const char *buf, size_t count) | ||
| 170 | { | ||
| 171 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 172 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 173 | |||
| 174 | unsigned long val; | ||
| 175 | |||
| 176 | if (strict_strtoul(buf, 0, &val)) | ||
| 177 | return -EINVAL; | ||
| 178 | |||
| 179 | if (val > nd->sensor_physical_height) | ||
| 180 | return -EINVAL; | ||
| 181 | |||
| 182 | nd->min_height = val * nd->sensor_logical_height / | ||
| 183 | nd->sensor_physical_height; | ||
| 184 | |||
| 185 | return count; | ||
| 186 | } | ||
| 187 | |||
| 188 | static DEVICE_ATTR(min_height, S_IWUSR | S_IRUGO, show_min_height, | ||
| 189 | set_min_height); | ||
| 190 | |||
| 191 | static ssize_t show_activate_slack(struct device *dev, | ||
| 192 | struct device_attribute *attr, | ||
| 193 | char *buf) | ||
| 194 | { | ||
| 195 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 196 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 197 | |||
| 198 | return sprintf(buf, "%d\n", nd->activate_slack); | ||
| 199 | } | ||
| 200 | |||
| 201 | static ssize_t set_activate_slack(struct device *dev, | ||
| 202 | struct device_attribute *attr, | ||
| 203 | const char *buf, size_t count) | ||
| 204 | { | ||
| 205 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 206 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 207 | |||
| 208 | unsigned long val; | ||
| 209 | |||
| 210 | if (strict_strtoul(buf, 0, &val)) | ||
| 211 | return -EINVAL; | ||
| 212 | |||
| 213 | if (val > 0x7f) | ||
| 214 | return -EINVAL; | ||
| 215 | |||
| 216 | nd->activate_slack = val; | ||
| 217 | |||
| 218 | return count; | ||
| 219 | } | ||
| 220 | |||
| 221 | static DEVICE_ATTR(activate_slack, S_IWUSR | S_IRUGO, show_activate_slack, | ||
| 222 | set_activate_slack); | ||
| 223 | |||
| 224 | static ssize_t show_activation_width(struct device *dev, | ||
| 225 | struct device_attribute *attr, | ||
| 226 | char *buf) | ||
| 227 | { | ||
| 228 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 229 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 230 | |||
| 231 | return sprintf(buf, "%d\n", nd->activation_width * | ||
| 232 | nd->sensor_physical_width / | ||
| 233 | nd->sensor_logical_width); | ||
| 234 | } | ||
| 235 | |||
| 236 | static ssize_t set_activation_width(struct device *dev, | ||
| 237 | struct device_attribute *attr, | ||
| 238 | const char *buf, size_t count) | ||
| 239 | { | ||
| 240 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 241 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 242 | |||
| 243 | unsigned long val; | ||
| 244 | |||
| 245 | if (strict_strtoul(buf, 0, &val)) | ||
| 246 | return -EINVAL; | ||
| 247 | |||
| 248 | if (val > nd->sensor_physical_width) | ||
| 249 | return -EINVAL; | ||
| 250 | |||
| 251 | nd->activation_width = val * nd->sensor_logical_width / | ||
| 252 | nd->sensor_physical_width; | ||
| 253 | |||
| 254 | return count; | ||
| 255 | } | ||
| 256 | |||
| 257 | static DEVICE_ATTR(activation_width, S_IWUSR | S_IRUGO, show_activation_width, | ||
| 258 | set_activation_width); | ||
| 259 | |||
| 260 | static ssize_t show_activation_height(struct device *dev, | ||
| 261 | struct device_attribute *attr, | ||
| 262 | char *buf) | ||
| 263 | { | ||
| 264 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 265 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 266 | |||
| 267 | return sprintf(buf, "%d\n", nd->activation_height * | ||
| 268 | nd->sensor_physical_height / | ||
| 269 | nd->sensor_logical_height); | ||
| 270 | } | ||
| 271 | |||
| 272 | static ssize_t set_activation_height(struct device *dev, | ||
| 273 | struct device_attribute *attr, | ||
| 274 | const char *buf, size_t count) | ||
| 275 | { | ||
| 276 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 277 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 278 | |||
| 279 | unsigned long val; | ||
| 280 | |||
| 281 | if (strict_strtoul(buf, 0, &val)) | ||
| 282 | return -EINVAL; | ||
| 283 | |||
| 284 | if (val > nd->sensor_physical_height) | ||
| 285 | return -EINVAL; | ||
| 286 | |||
| 287 | nd->activation_height = val * nd->sensor_logical_height / | ||
| 288 | nd->sensor_physical_height; | ||
| 289 | |||
| 290 | return count; | ||
| 291 | } | ||
| 292 | |||
| 293 | static DEVICE_ATTR(activation_height, S_IWUSR | S_IRUGO, | ||
| 294 | show_activation_height, set_activation_height); | ||
| 295 | |||
| 296 | static ssize_t show_deactivate_slack(struct device *dev, | ||
| 297 | struct device_attribute *attr, | ||
| 298 | char *buf) | ||
| 299 | { | ||
| 300 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 301 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 302 | |||
| 303 | return sprintf(buf, "%d\n", -nd->deactivate_slack); | ||
| 304 | } | ||
| 305 | |||
| 306 | static ssize_t set_deactivate_slack(struct device *dev, | ||
| 307 | struct device_attribute *attr, | ||
| 308 | const char *buf, size_t count) | ||
| 309 | { | ||
| 310 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
| 311 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
| 312 | |||
| 313 | unsigned long val; | ||
| 314 | |||
| 315 | if (strict_strtoul(buf, 0, &val)) | ||
| 316 | return -EINVAL; | ||
| 317 | |||
| 318 | /* | ||
| 319 | * No more than 8 terminal frames have been observed so far | ||
| 320 | * and higher slack is highly likely to leave the single | ||
| 321 | * touch emulation stuck down. | ||
| 322 | */ | ||
| 323 | if (val > 7) | ||
| 324 | return -EINVAL; | ||
| 325 | |||
| 326 | nd->deactivate_slack = -val; | ||
| 327 | |||
| 328 | return count; | ||
| 329 | } | ||
| 330 | |||
| 331 | static DEVICE_ATTR(deactivate_slack, S_IWUSR | S_IRUGO, show_deactivate_slack, | ||
| 332 | set_deactivate_slack); | ||
| 333 | |||
| 334 | static struct attribute *sysfs_attrs[] = { | ||
| 335 | &dev_attr_sensor_physical_width.attr, | ||
| 336 | &dev_attr_sensor_physical_height.attr, | ||
| 337 | &dev_attr_sensor_logical_width.attr, | ||
| 338 | &dev_attr_sensor_logical_height.attr, | ||
| 339 | &dev_attr_min_height.attr, | ||
| 340 | &dev_attr_min_width.attr, | ||
| 341 | &dev_attr_activate_slack.attr, | ||
| 342 | &dev_attr_activation_width.attr, | ||
| 343 | &dev_attr_activation_height.attr, | ||
| 344 | &dev_attr_deactivate_slack.attr, | ||
| 345 | NULL | ||
| 346 | }; | ||
| 347 | |||
| 348 | static struct attribute_group ntrig_attribute_group = { | ||
| 349 | .attrs = sysfs_attrs | ||
| 350 | }; | ||
| 351 | |||
| 71 | /* | 352 | /* |
| 72 | * this driver is aimed at two firmware versions in circulation: | 353 | * this driver is aimed at two firmware versions in circulation: |
| 73 | * - dual pen/finger single touch | 354 | * - dual pen/finger single touch |
| @@ -546,6 +827,8 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 546 | if (report) | 827 | if (report) |
| 547 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 828 | usbhid_submit_report(hdev, report, USB_DIR_OUT); |
| 548 | 829 | ||
| 830 | ret = sysfs_create_group(&hdev->dev.kobj, | ||
| 831 | &ntrig_attribute_group); | ||
| 549 | 832 | ||
| 550 | return 0; | 833 | return 0; |
| 551 | err_free: | 834 | err_free: |
| @@ -555,6 +838,8 @@ err_free: | |||
| 555 | 838 | ||
| 556 | static void ntrig_remove(struct hid_device *hdev) | 839 | static void ntrig_remove(struct hid_device *hdev) |
| 557 | { | 840 | { |
| 841 | sysfs_remove_group(&hdev->dev.kobj, | ||
| 842 | &ntrig_attribute_group); | ||
| 558 | hid_hw_stop(hdev); | 843 | hid_hw_stop(hdev); |
| 559 | kfree(hid_get_drvdata(hdev)); | 844 | kfree(hid_get_drvdata(hdev)); |
| 560 | } | 845 | } |
