hwmon: (hdaps) Allow inversion of separate axis
Fix for kernel.org bug #7154: hdaps inversion of each axis. This version is based on the work from Michael Ruoss <miruoss@student.ethz.ch>. Signed-off-by: Frank Seidel <frank@f-seidel.de> Signed-off-by: Jean Delvare <khali@linux-fr.org>
This commit is contained in:
parent
25f3311acc
commit
2b8cf3e8c0
@ -65,6 +65,10 @@
|
|||||||
#define HDAPS_INPUT_FUZZ 4 /* input event threshold */
|
#define HDAPS_INPUT_FUZZ 4 /* input event threshold */
|
||||||
#define HDAPS_INPUT_FLAT 4
|
#define HDAPS_INPUT_FLAT 4
|
||||||
|
|
||||||
|
#define HDAPS_X_AXIS (1 << 0)
|
||||||
|
#define HDAPS_Y_AXIS (1 << 1)
|
||||||
|
#define HDAPS_BOTH_AXES (HDAPS_X_AXIS | HDAPS_Y_AXIS)
|
||||||
|
|
||||||
static struct platform_device *pdev;
|
static struct platform_device *pdev;
|
||||||
static struct input_polled_dev *hdaps_idev;
|
static struct input_polled_dev *hdaps_idev;
|
||||||
static unsigned int hdaps_invert;
|
static unsigned int hdaps_invert;
|
||||||
@ -182,11 +186,11 @@ static int __hdaps_read_pair(unsigned int port1, unsigned int port2,
|
|||||||
km_activity = inb(HDAPS_PORT_KMACT);
|
km_activity = inb(HDAPS_PORT_KMACT);
|
||||||
__device_complete();
|
__device_complete();
|
||||||
|
|
||||||
/* if hdaps_invert is set, negate the two values */
|
/* hdaps_invert is a bitvector to negate the axes */
|
||||||
if (hdaps_invert) {
|
if (hdaps_invert & HDAPS_X_AXIS)
|
||||||
*x = -*x;
|
*x = -*x;
|
||||||
|
if (hdaps_invert & HDAPS_Y_AXIS)
|
||||||
*y = -*y;
|
*y = -*y;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -436,7 +440,8 @@ static ssize_t hdaps_invert_store(struct device *dev,
|
|||||||
{
|
{
|
||||||
int invert;
|
int invert;
|
||||||
|
|
||||||
if (sscanf(buf, "%d", &invert) != 1 || (invert != 1 && invert != 0))
|
if (sscanf(buf, "%d", &invert) != 1 ||
|
||||||
|
invert < 0 || invert > HDAPS_BOTH_AXES)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
hdaps_invert = invert;
|
hdaps_invert = invert;
|
||||||
@ -483,56 +488,52 @@ static int __init hdaps_dmi_match(const struct dmi_system_id *id)
|
|||||||
/* hdaps_dmi_match_invert - found an inverted match. */
|
/* hdaps_dmi_match_invert - found an inverted match. */
|
||||||
static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id)
|
static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id)
|
||||||
{
|
{
|
||||||
hdaps_invert = 1;
|
hdaps_invert = (unsigned long)id->driver_data;
|
||||||
printk(KERN_INFO "hdaps: inverting axis readings.\n");
|
printk(KERN_INFO "hdaps: inverting axis (%u) readings.\n",
|
||||||
|
hdaps_invert);
|
||||||
return hdaps_dmi_match(id);
|
return hdaps_dmi_match(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HDAPS_DMI_MATCH_NORMAL(vendor, model) { \
|
#define HDAPS_DMI_MATCH_INVERT(vendor, model, axes) { \
|
||||||
.ident = vendor " " model, \
|
.ident = vendor " " model, \
|
||||||
.callback = hdaps_dmi_match, \
|
.callback = hdaps_dmi_match_invert, \
|
||||||
|
.driver_data = (void *)axes, \
|
||||||
.matches = { \
|
.matches = { \
|
||||||
DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
|
DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
|
||||||
DMI_MATCH(DMI_PRODUCT_VERSION, model) \
|
DMI_MATCH(DMI_PRODUCT_VERSION, model) \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HDAPS_DMI_MATCH_INVERT(vendor, model) { \
|
#define HDAPS_DMI_MATCH_NORMAL(vendor, model) \
|
||||||
.ident = vendor " " model, \
|
HDAPS_DMI_MATCH_INVERT(vendor, model, 0)
|
||||||
.callback = hdaps_dmi_match_invert, \
|
|
||||||
.matches = { \
|
|
||||||
DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
|
|
||||||
DMI_MATCH(DMI_PRODUCT_VERSION, model) \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
|
/* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
|
||||||
"ThinkPad T42p", so the order of the entries matters.
|
"ThinkPad T42p", so the order of the entries matters.
|
||||||
If your ThinkPad is not recognized, please update to latest
|
If your ThinkPad is not recognized, please update to latest
|
||||||
BIOS. This is especially the case for some R52 ThinkPads. */
|
BIOS. This is especially the case for some R52 ThinkPads. */
|
||||||
static struct dmi_system_id __initdata hdaps_whitelist[] = {
|
static struct dmi_system_id __initdata hdaps_whitelist[] = {
|
||||||
HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p"),
|
HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"),
|
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"),
|
||||||
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"),
|
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"),
|
||||||
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"),
|
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"),
|
||||||
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i"),
|
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61"),
|
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"),
|
HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"),
|
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"),
|
||||||
HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"),
|
HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"),
|
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"),
|
||||||
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"),
|
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"),
|
||||||
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"),
|
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p"),
|
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61"),
|
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"),
|
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"),
|
||||||
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"),
|
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"),
|
||||||
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"),
|
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s"),
|
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61"),
|
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"),
|
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"),
|
||||||
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m"),
|
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m", HDAPS_BOTH_AXES),
|
||||||
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p"),
|
HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p", HDAPS_BOTH_AXES),
|
||||||
{ .ident = NULL }
|
{ .ident = NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -627,8 +628,9 @@ static void __exit hdaps_exit(void)
|
|||||||
module_init(hdaps_init);
|
module_init(hdaps_init);
|
||||||
module_exit(hdaps_exit);
|
module_exit(hdaps_exit);
|
||||||
|
|
||||||
module_param_named(invert, hdaps_invert, bool, 0);
|
module_param_named(invert, hdaps_invert, int, 0);
|
||||||
MODULE_PARM_DESC(invert, "invert data along each axis");
|
MODULE_PARM_DESC(invert, "invert data along each axis. 1 invert x-axis, "
|
||||||
|
"2 invert y-axis, 3 invert both axes.");
|
||||||
|
|
||||||
MODULE_AUTHOR("Robert Love");
|
MODULE_AUTHOR("Robert Love");
|
||||||
MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver");
|
MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver");
|
||||||
|
Loading…
Reference in New Issue
Block a user