diff options
| author | Frank Seidel <frank@f-seidel.de> | 2009-03-30 15:46:41 -0400 |
|---|---|---|
| committer | Jean Delvare <khali@linux-fr.org> | 2009-03-30 15:46:41 -0400 |
| commit | 2b8cf3e8c0638687a7a28a7517e673f855623e3b (patch) | |
| tree | 0c549bbfb7d6f195d9e1e7b0412ae96884d311d0 | |
| parent | 25f3311acc3405dd0dace3571a41f450e6cc6a65 (diff) | |
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>
| -rw-r--r-- | drivers/hwmon/hdaps.c | 64 |
1 files changed, 33 insertions, 31 deletions
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index a4d92d246d52..dd058e06e344 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c | |||
| @@ -65,6 +65,10 @@ | |||
| 65 | #define HDAPS_INPUT_FUZZ 4 /* input event threshold */ | 65 | #define HDAPS_INPUT_FUZZ 4 /* input event threshold */ |
| 66 | #define HDAPS_INPUT_FLAT 4 | 66 | #define HDAPS_INPUT_FLAT 4 |
| 67 | 67 | ||
| 68 | #define HDAPS_X_AXIS (1 << 0) | ||
| 69 | #define HDAPS_Y_AXIS (1 << 1) | ||
| 70 | #define HDAPS_BOTH_AXES (HDAPS_X_AXIS | HDAPS_Y_AXIS) | ||
| 71 | |||
| 68 | static struct platform_device *pdev; | 72 | static struct platform_device *pdev; |
| 69 | static struct input_polled_dev *hdaps_idev; | 73 | static struct input_polled_dev *hdaps_idev; |
| 70 | static unsigned int hdaps_invert; | 74 | static unsigned int hdaps_invert; |
| @@ -182,11 +186,11 @@ static int __hdaps_read_pair(unsigned int port1, unsigned int port2, | |||
| 182 | km_activity = inb(HDAPS_PORT_KMACT); | 186 | km_activity = inb(HDAPS_PORT_KMACT); |
| 183 | __device_complete(); | 187 | __device_complete(); |
| 184 | 188 | ||
| 185 | /* if hdaps_invert is set, negate the two values */ | 189 | /* hdaps_invert is a bitvector to negate the axes */ |
| 186 | if (hdaps_invert) { | 190 | if (hdaps_invert & HDAPS_X_AXIS) |
| 187 | *x = -*x; | 191 | *x = -*x; |
| 192 | if (hdaps_invert & HDAPS_Y_AXIS) | ||
| 188 | *y = -*y; | 193 | *y = -*y; |
| 189 | } | ||
| 190 | 194 | ||
| 191 | return 0; | 195 | return 0; |
| 192 | } | 196 | } |
| @@ -436,7 +440,8 @@ static ssize_t hdaps_invert_store(struct device *dev, | |||
| 436 | { | 440 | { |
| 437 | int invert; | 441 | int invert; |
| 438 | 442 | ||
| 439 | if (sscanf(buf, "%d", &invert) != 1 || (invert != 1 && invert != 0)) | 443 | if (sscanf(buf, "%d", &invert) != 1 || |
| 444 | invert < 0 || invert > HDAPS_BOTH_AXES) | ||
| 440 | return -EINVAL; | 445 | return -EINVAL; |
| 441 | 446 | ||
| 442 | hdaps_invert = invert; | 447 | hdaps_invert = invert; |
| @@ -483,56 +488,52 @@ static int __init hdaps_dmi_match(const struct dmi_system_id *id) | |||
| 483 | /* hdaps_dmi_match_invert - found an inverted match. */ | 488 | /* hdaps_dmi_match_invert - found an inverted match. */ |
| 484 | static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id) | 489 | static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id) |
| 485 | { | 490 | { |
| 486 | hdaps_invert = 1; | 491 | hdaps_invert = (unsigned long)id->driver_data; |
| 487 | printk(KERN_INFO "hdaps: inverting axis readings.\n"); | 492 | printk(KERN_INFO "hdaps: inverting axis (%u) readings.\n", |
| 493 | hdaps_invert); | ||
| 488 | return hdaps_dmi_match(id); | 494 | return hdaps_dmi_match(id); |
| 489 | } | 495 | } |
| 490 | 496 | ||
| 491 | #define HDAPS_DMI_MATCH_NORMAL(vendor, model) { \ | 497 | #define HDAPS_DMI_MATCH_INVERT(vendor, model, axes) { \ |
| 492 | .ident = vendor " " model, \ | ||
| 493 | .callback = hdaps_dmi_match, \ | ||
| 494 | .matches = { \ | ||
| 495 | DMI_MATCH(DMI_BOARD_VENDOR, vendor), \ | ||
| 496 | DMI_MATCH(DMI_PRODUCT_VERSION, model) \ | ||
| 497 | } \ | ||
| 498 | } | ||
| 499 | |||
| 500 | #define HDAPS_DMI_MATCH_INVERT(vendor, model) { \ | ||
| 501 | .ident = vendor " " model, \ | 498 | .ident = vendor " " model, \ |
| 502 | .callback = hdaps_dmi_match_invert, \ | 499 | .callback = hdaps_dmi_match_invert, \ |
| 500 | .driver_data = (void *)axes, \ | ||
| 503 | .matches = { \ | 501 | .matches = { \ |
| 504 | DMI_MATCH(DMI_BOARD_VENDOR, vendor), \ | 502 | DMI_MATCH(DMI_BOARD_VENDOR, vendor), \ |
| 505 | DMI_MATCH(DMI_PRODUCT_VERSION, model) \ | 503 | DMI_MATCH(DMI_PRODUCT_VERSION, model) \ |
| 506 | } \ | 504 | } \ |
| 507 | } | 505 | } |
| 508 | 506 | ||
| 507 | #define HDAPS_DMI_MATCH_NORMAL(vendor, model) \ | ||
| 508 | HDAPS_DMI_MATCH_INVERT(vendor, model, 0) | ||
| 509 | |||
| 509 | /* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match | 510 | /* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match |
| 510 | "ThinkPad T42p", so the order of the entries matters. | 511 | "ThinkPad T42p", so the order of the entries matters. |
| 511 | If your ThinkPad is not recognized, please update to latest | 512 | If your ThinkPad is not recognized, please update to latest |
| 512 | BIOS. This is especially the case for some R52 ThinkPads. */ | 513 | BIOS. This is especially the case for some R52 ThinkPads. */ |
| 513 | static struct dmi_system_id __initdata hdaps_whitelist[] = { | 514 | static struct dmi_system_id __initdata hdaps_whitelist[] = { |
| 514 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p"), | 515 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p", HDAPS_BOTH_AXES), |
| 515 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"), | 516 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"), |
| 516 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"), | 517 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"), |
| 517 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"), | 518 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"), |
| 518 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i"), | 519 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i", HDAPS_BOTH_AXES), |
| 519 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61"), | 520 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61", HDAPS_BOTH_AXES), |
| 520 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"), | 521 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p", HDAPS_BOTH_AXES), |
| 521 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"), | 522 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"), |
| 522 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"), | 523 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p", HDAPS_BOTH_AXES), |
| 523 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"), | 524 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"), |
| 524 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"), | 525 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"), |
| 525 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"), | 526 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60", HDAPS_BOTH_AXES), |
| 526 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p"), | 527 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p", HDAPS_BOTH_AXES), |
| 527 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61"), | 528 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61", HDAPS_BOTH_AXES), |
| 528 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"), | 529 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"), |
| 529 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"), | 530 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"), |
| 530 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"), | 531 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60", HDAPS_BOTH_AXES), |
| 531 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s"), | 532 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s", HDAPS_BOTH_AXES), |
| 532 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61"), | 533 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61", HDAPS_BOTH_AXES), |
| 533 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"), | 534 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"), |
| 534 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m"), | 535 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m", HDAPS_BOTH_AXES), |
| 535 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p"), | 536 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p", HDAPS_BOTH_AXES), |
| 536 | { .ident = NULL } | 537 | { .ident = NULL } |
| 537 | }; | 538 | }; |
| 538 | 539 | ||
| @@ -627,8 +628,9 @@ static void __exit hdaps_exit(void) | |||
| 627 | module_init(hdaps_init); | 628 | module_init(hdaps_init); |
| 628 | module_exit(hdaps_exit); | 629 | module_exit(hdaps_exit); |
| 629 | 630 | ||
| 630 | module_param_named(invert, hdaps_invert, bool, 0); | 631 | module_param_named(invert, hdaps_invert, int, 0); |
| 631 | MODULE_PARM_DESC(invert, "invert data along each axis"); | 632 | MODULE_PARM_DESC(invert, "invert data along each axis. 1 invert x-axis, " |
| 633 | "2 invert y-axis, 3 invert both axes."); | ||
| 632 | 634 | ||
| 633 | MODULE_AUTHOR("Robert Love"); | 635 | MODULE_AUTHOR("Robert Love"); |
| 634 | MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver"); | 636 | MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver"); |
