diff options
Diffstat (limited to 'drivers/platform/x86/acerhdf.c')
-rw-r--r-- | drivers/platform/x86/acerhdf.c | 119 |
1 files changed, 77 insertions, 42 deletions
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index ab64522aaa64..7b2384d674d0 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c | |||
@@ -52,7 +52,7 @@ | |||
52 | */ | 52 | */ |
53 | #undef START_IN_KERNEL_MODE | 53 | #undef START_IN_KERNEL_MODE |
54 | 54 | ||
55 | #define DRV_VER "0.5.18" | 55 | #define DRV_VER "0.5.22" |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * According to the Atom N270 datasheet, | 58 | * According to the Atom N270 datasheet, |
@@ -112,12 +112,14 @@ module_param_string(force_product, force_product, 16, 0); | |||
112 | MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check"); | 112 | MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check"); |
113 | 113 | ||
114 | /* | 114 | /* |
115 | * cmd_off: to switch the fan completely off / to check if the fan is off | 115 | * cmd_off: to switch the fan completely off |
116 | * chk_off: to check if the fan is off | ||
116 | * cmd_auto: to set the BIOS in control of the fan. The BIOS regulates then | 117 | * cmd_auto: to set the BIOS in control of the fan. The BIOS regulates then |
117 | * the fan speed depending on the temperature | 118 | * the fan speed depending on the temperature |
118 | */ | 119 | */ |
119 | struct fancmd { | 120 | struct fancmd { |
120 | u8 cmd_off; | 121 | u8 cmd_off; |
122 | u8 chk_off; | ||
121 | u8 cmd_auto; | 123 | u8 cmd_auto; |
122 | }; | 124 | }; |
123 | 125 | ||
@@ -134,32 +136,47 @@ struct bios_settings_t { | |||
134 | /* Register addresses and values for different BIOS versions */ | 136 | /* Register addresses and values for different BIOS versions */ |
135 | static const struct bios_settings_t bios_tbl[] = { | 137 | static const struct bios_settings_t bios_tbl[] = { |
136 | /* AOA110 */ | 138 | /* AOA110 */ |
137 | {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00} }, | 139 | {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x1f, 0x00} }, |
138 | {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00} }, | 140 | {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x1f, 0x00} }, |
139 | {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0x00} }, | 141 | {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0xaf, 0x00} }, |
140 | {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0x00} }, | 142 | {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0xaf, 0x00} }, |
141 | {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0x00} }, | 143 | {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0xaf, 0x00} }, |
142 | {"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0x00} }, | 144 | {"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0xaf, 0x00} }, |
143 | {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x00} }, | 145 | {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x21, 0x00} }, |
144 | {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00} }, | 146 | {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x21, 0x00} }, |
145 | {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00} }, | 147 | {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x21, 0x00} }, |
146 | /* AOA150 */ | 148 | /* AOA150 */ |
147 | {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x00} }, | 149 | {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
148 | {"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x00} }, | 150 | {"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
149 | {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00} }, | 151 | {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
150 | {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00} }, | 152 | {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
151 | {"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x00} }, | 153 | {"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
152 | {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} }, | 154 | {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
153 | {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} }, | 155 | {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
154 | {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} }, | 156 | {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
155 | /* special BIOS / other */ | 157 | /* Acer 1410 */ |
156 | {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, | 158 | {"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, |
157 | {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} }, | 159 | {"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, |
158 | {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} }, | 160 | /* Acer 1810xx */ |
159 | {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, | 161 | {"Acer", "Aspire 1810TZ", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, |
160 | {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, | 162 | {"Acer", "Aspire 1810T", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, |
163 | {"Acer", "Aspire 1810T", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, | ||
164 | {"Acer", "Aspire 1810TZ", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, | ||
165 | /* Gateway */ | ||
166 | {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} }, | ||
167 | {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} }, | ||
168 | {"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x10, 0x0f, 0x00} }, | ||
169 | {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x10, 0x0f, 0x00} }, | ||
170 | {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x10, 0x0f, 0x00} }, | ||
171 | /* Packard Bell */ | ||
172 | {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} }, | ||
173 | {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, | ||
174 | {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x21, 0x00} }, | ||
175 | {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, | ||
176 | {"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, | ||
177 | {"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, | ||
161 | /* pewpew-terminator */ | 178 | /* pewpew-terminator */ |
162 | {"", "", "", 0, 0, {0, 0} } | 179 | {"", "", "", 0, 0, {0, 0, 0} } |
163 | }; | 180 | }; |
164 | 181 | ||
165 | static const struct bios_settings_t *bios_cfg __read_mostly; | 182 | static const struct bios_settings_t *bios_cfg __read_mostly; |
@@ -183,7 +200,7 @@ static int acerhdf_get_fanstate(int *state) | |||
183 | if (ec_read(bios_cfg->fanreg, &fan)) | 200 | if (ec_read(bios_cfg->fanreg, &fan)) |
184 | return -EINVAL; | 201 | return -EINVAL; |
185 | 202 | ||
186 | if (fan != bios_cfg->cmd.cmd_off) | 203 | if (fan != bios_cfg->cmd.chk_off) |
187 | *state = ACERHDF_FAN_AUTO; | 204 | *state = ACERHDF_FAN_AUTO; |
188 | else | 205 | else |
189 | *state = ACERHDF_FAN_OFF; | 206 | *state = ACERHDF_FAN_OFF; |
@@ -460,7 +477,7 @@ static int acerhdf_remove(struct platform_device *device) | |||
460 | return 0; | 477 | return 0; |
461 | } | 478 | } |
462 | 479 | ||
463 | static struct dev_pm_ops acerhdf_pm_ops = { | 480 | static const struct dev_pm_ops acerhdf_pm_ops = { |
464 | .suspend = acerhdf_suspend, | 481 | .suspend = acerhdf_suspend, |
465 | .freeze = acerhdf_suspend, | 482 | .freeze = acerhdf_suspend, |
466 | }; | 483 | }; |
@@ -475,13 +492,26 @@ static struct platform_driver acerhdf_driver = { | |||
475 | .remove = acerhdf_remove, | 492 | .remove = acerhdf_remove, |
476 | }; | 493 | }; |
477 | 494 | ||
495 | /* checks if str begins with start */ | ||
496 | static int str_starts_with(const char *str, const char *start) | ||
497 | { | ||
498 | unsigned long str_len = 0, start_len = 0; | ||
499 | |||
500 | str_len = strlen(str); | ||
501 | start_len = strlen(start); | ||
502 | |||
503 | if (str_len >= start_len && | ||
504 | !strncmp(str, start, start_len)) | ||
505 | return 1; | ||
506 | |||
507 | return 0; | ||
508 | } | ||
478 | 509 | ||
479 | /* check hardware */ | 510 | /* check hardware */ |
480 | static int acerhdf_check_hardware(void) | 511 | static int acerhdf_check_hardware(void) |
481 | { | 512 | { |
482 | char const *vendor, *version, *product; | 513 | char const *vendor, *version, *product; |
483 | int i; | 514 | const struct bios_settings_t *bt = NULL; |
484 | unsigned long prod_len = 0; | ||
485 | 515 | ||
486 | /* get BIOS data */ | 516 | /* get BIOS data */ |
487 | vendor = dmi_get_system_info(DMI_SYS_VENDOR); | 517 | vendor = dmi_get_system_info(DMI_SYS_VENDOR); |
@@ -503,20 +533,20 @@ static int acerhdf_check_hardware(void) | |||
503 | kernelmode = 0; | 533 | kernelmode = 0; |
504 | } | 534 | } |
505 | 535 | ||
506 | prod_len = strlen(product); | ||
507 | |||
508 | if (verbose) | 536 | if (verbose) |
509 | pr_info("BIOS info: %s %s, product: %s\n", | 537 | pr_info("BIOS info: %s %s, product: %s\n", |
510 | vendor, version, product); | 538 | vendor, version, product); |
511 | 539 | ||
512 | /* search BIOS version and vendor in BIOS settings table */ | 540 | /* search BIOS version and vendor in BIOS settings table */ |
513 | for (i = 0; bios_tbl[i].version[0]; i++) { | 541 | for (bt = bios_tbl; bt->vendor[0]; bt++) { |
514 | if (strlen(bios_tbl[i].product) >= prod_len && | 542 | /* |
515 | !strncmp(bios_tbl[i].product, product, | 543 | * check if actual hardware BIOS vendor, product and version |
516 | strlen(bios_tbl[i].product)) && | 544 | * IDs start with the strings of BIOS table entry |
517 | !strcmp(bios_tbl[i].vendor, vendor) && | 545 | */ |
518 | !strcmp(bios_tbl[i].version, version)) { | 546 | if (str_starts_with(vendor, bt->vendor) && |
519 | bios_cfg = &bios_tbl[i]; | 547 | str_starts_with(product, bt->product) && |
548 | str_starts_with(version, bt->version)) { | ||
549 | bios_cfg = bt; | ||
520 | break; | 550 | break; |
521 | } | 551 | } |
522 | } | 552 | } |
@@ -629,9 +659,14 @@ static void __exit acerhdf_exit(void) | |||
629 | MODULE_LICENSE("GPL"); | 659 | MODULE_LICENSE("GPL"); |
630 | MODULE_AUTHOR("Peter Feuerer"); | 660 | MODULE_AUTHOR("Peter Feuerer"); |
631 | MODULE_DESCRIPTION("Aspire One temperature and fan driver"); | 661 | MODULE_DESCRIPTION("Aspire One temperature and fan driver"); |
632 | MODULE_ALIAS("dmi:*:*Acer*:*:"); | 662 | MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); |
633 | MODULE_ALIAS("dmi:*:*Gateway*:*:"); | 663 | MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1410*:"); |
634 | MODULE_ALIAS("dmi:*:*Packard Bell*:*:"); | 664 | MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1810*:"); |
665 | MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:"); | ||
666 | MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:"); | ||
667 | MODULE_ALIAS("dmi:*:*Packard Bell*:pnAOA*:"); | ||
668 | MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOA*:"); | ||
669 | MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOTMU*:"); | ||
635 | 670 | ||
636 | module_init(acerhdf_init); | 671 | module_init(acerhdf_init); |
637 | module_exit(acerhdf_exit); | 672 | module_exit(acerhdf_exit); |