/*
* HID driver for N-Trig touchscreens
*
* Copyright (c) 2008-2010 Rafi Rubin
* Copyright (c) 2009-2010 Stephane Chatty
*
*/
/*
* 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.
*/
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/usb.h>
#include "usbhid/usbhid.h"
#include <linux/module.h>
#include <linux/slab.h>
#include "hid-ids.h"
#define NTRIG_DUPLICATE_USAGES 0x001
static unsigned int min_width;
module_param(min_width, uint, 0644);
MODULE_PARM_DESC(min_width, "Minimum touch contact width to accept.");
static unsigned int min_height;
module_param(min_height, uint, 0644);
MODULE_PARM_DESC(min_height, "Minimum touch contact height to accept.");
static unsigned int activate_slack = 1;
module_param(activate_slack, uint, 0644);
MODULE_PARM_DESC(activate_slack, "Number of touch frames to ignore at "
"the start of touch input.");
static unsigned int deactivate_slack = 4;
module_param(deactivate_slack, uint, 0644);
MODULE_PARM_DESC(deactivate_slack, "Number of empty frames to ignore before "
"deactivating touch.");
static unsigned int activation_width = 64;
module_param(activation_width, uint, 0644);
MODULE_PARM_DESC(activation_width, "Width threshold to immediately start "
"processing touch events.");
static unsigned int activation_height = 32;
module_param(activation_height, uint, 0644);
MODULE_PARM_DESC(activation_height, "Height threshold to immediately start "
"processing touch events.");
struct ntrig_data {
/* Incoming raw values for a single contact */
__u16 x, y, w, h;
__u16 id;
bool tipswitch;
bool confidence;
bool first_contact_touch;
bool reading_mt;
__u8 mt_footer[4];
__u8 mt_foot_count;
/* The current activation state. */
__s8 act_state;
/* Empty frames to ignore before recognizing the end of activity */
__s8 deactivate_slack;
/* Frames to ignore before acknowledging the start of activity */
__s8 activate_slack;
/* Minimum size contact to accept */
__u16 min_width;
__u16 min_height;
/* Threshold to override activation slack */
__u16 activation_width;
__u16 activation_height;
__u16 sensor_logical_width;
__u16 sensor_logical_height;
__u16 sensor_physical_width;
__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<