aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/acerhdf.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 12:32:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 12:32:11 -0400
commitc11f6c82581e8be4e1829c677db54e7f55cebece (patch)
tree1a116241b0831ded998aabe800bdc24104cbd826 /drivers/platform/x86/acerhdf.c
parent40aba218969914d1b225e742617adb921cf94eae (diff)
parent193a6dec1c0246a80b6d0101e4f351ccf877bcac (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (119 commits) ACPI: don't pass handle for fixed hardware notifications ACPI: remove null pointer checks in deferred execution path ACPI: simplify deferred execution path acerhdf: additional BIOS versions acerhdf: convert to dev_pm_ops acerhdf: fix fan control for AOA150 model thermal: add missing Kconfig dependency acpi: switch /proc/acpi/{debug_layer,debug_level} to seq_file hp-wmi: fix rfkill memory leak on unload ACPI: remove unnecessary #ifdef CONFIG_DMI ACPI: linux/acpi.h should not include linux/dmi.h hwmon driver for ACPI 4.0 power meters topstar-laptop: add new driver for hotkeys support on Topstar N01 thinkpad_acpi: fix rfkill memory leak on unload thinkpad-acpi: report brightness events when required thinkpad-acpi: don't poll by default any of the reserved hotkeys thinkpad-acpi: Fix procfs hotkey reset command thinkpad-acpi: deprecate hotkey_bios_mask thinkpad-acpi: hotkey poll fixes thinkpad-acpi: be more strict when detecting a ThinkPad ...
Diffstat (limited to 'drivers/platform/x86/acerhdf.c')
-rw-r--r--drivers/platform/x86/acerhdf.c121
1 files changed, 78 insertions, 43 deletions
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index bdfee177eefb..0a8f735f6c4a 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.13" 55#define DRV_VER "0.5.17"
56 56
57/* 57/*
58 * According to the Atom N270 datasheet, 58 * According to the Atom N270 datasheet,
@@ -90,6 +90,7 @@ static unsigned int fanoff = 58;
90static unsigned int verbose; 90static unsigned int verbose;
91static unsigned int fanstate = ACERHDF_FAN_AUTO; 91static unsigned int fanstate = ACERHDF_FAN_AUTO;
92static char force_bios[16]; 92static char force_bios[16];
93static char force_product[16];
93static unsigned int prev_interval; 94static unsigned int prev_interval;
94struct thermal_zone_device *thz_dev; 95struct thermal_zone_device *thz_dev;
95struct thermal_cooling_device *cl_dev; 96struct thermal_cooling_device *cl_dev;
@@ -107,34 +108,62 @@ module_param(verbose, uint, 0600);
107MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); 108MODULE_PARM_DESC(verbose, "Enable verbose dmesg output");
108module_param_string(force_bios, force_bios, 16, 0); 109module_param_string(force_bios, force_bios, 16, 0);
109MODULE_PARM_DESC(force_bios, "Force BIOS version and omit BIOS check"); 110MODULE_PARM_DESC(force_bios, "Force BIOS version and omit BIOS check");
111module_param_string(force_product, force_product, 16, 0);
112MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check");
113
114/*
115 * cmd_off: to switch the fan completely 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 * the fan speed depending on the temperature
118 */
119struct fancmd {
120 u8 cmd_off;
121 u8 cmd_auto;
122};
110 123
111/* BIOS settings */ 124/* BIOS settings */
112struct bios_settings_t { 125struct bios_settings_t {
113 const char *vendor; 126 const char *vendor;
127 const char *product;
114 const char *version; 128 const char *version;
115 unsigned char fanreg; 129 unsigned char fanreg;
116 unsigned char tempreg; 130 unsigned char tempreg;
117 unsigned char fancmd[2]; /* fan off and auto commands */ 131 struct fancmd cmd;
118}; 132};
119 133
120/* Register addresses and values for different BIOS versions */ 134/* Register addresses and values for different BIOS versions */
121static const struct bios_settings_t bios_tbl[] = { 135static const struct bios_settings_t bios_tbl[] = {
122 {"Acer", "v0.3109", 0x55, 0x58, {0x1f, 0x00} }, 136 /* AOA110 */
123 {"Acer", "v0.3114", 0x55, 0x58, {0x1f, 0x00} }, 137 {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00} },
124 {"Acer", "v0.3301", 0x55, 0x58, {0xaf, 0x00} }, 138 {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00} },
125 {"Acer", "v0.3304", 0x55, 0x58, {0xaf, 0x00} }, 139 {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0x00} },
126 {"Acer", "v0.3305", 0x55, 0x58, {0xaf, 0x00} }, 140 {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0x00} },
127 {"Acer", "v0.3308", 0x55, 0x58, {0x21, 0x00} }, 141 {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0x00} },
128 {"Acer", "v0.3309", 0x55, 0x58, {0x21, 0x00} }, 142 {"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0x00} },
129 {"Acer", "v0.3310", 0x55, 0x58, {0x21, 0x00} }, 143 {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x00} },
130 {"Gateway", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, 144 {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00} },
131 {"Packard Bell", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, 145 {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00} },
132 {"", "", 0, 0, {0, 0} } 146 /* AOA150 */
147 {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x00} },
148 {"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x00} },
149 {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00} },
150 {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00} },
151 {"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x00} },
152 {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} },
153 {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} },
154 {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} },
155 /* special BIOS / other */
156 {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} },
157 {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} },
158 {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} },
159 {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} },
160 {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} },
161 /* pewpew-terminator */
162 {"", "", "", 0, 0, {0, 0} }
133}; 163};
134 164
135static const struct bios_settings_t *bios_cfg __read_mostly; 165static const struct bios_settings_t *bios_cfg __read_mostly;
136 166
137
138static int acerhdf_get_temp(int *temp) 167static int acerhdf_get_temp(int *temp)
139{ 168{
140 u8 read_temp; 169 u8 read_temp;
@@ -150,13 +179,14 @@ static int acerhdf_get_temp(int *temp)
150static int acerhdf_get_fanstate(int *state) 179static int acerhdf_get_fanstate(int *state)
151{ 180{
152 u8 fan; 181 u8 fan;
153 bool tmp;
154 182
155 if (ec_read(bios_cfg->fanreg, &fan)) 183 if (ec_read(bios_cfg->fanreg, &fan))
156 return -EINVAL; 184 return -EINVAL;
157 185
158 tmp = (fan == bios_cfg->fancmd[ACERHDF_FAN_OFF]); 186 if (fan != bios_cfg->cmd.cmd_off)
159 *state = tmp ? ACERHDF_FAN_OFF : ACERHDF_FAN_AUTO; 187 *state = ACERHDF_FAN_AUTO;
188 else
189 *state = ACERHDF_FAN_OFF;
160 190
161 return 0; 191 return 0;
162} 192}
@@ -175,7 +205,8 @@ static void acerhdf_change_fanstate(int state)
175 state = ACERHDF_FAN_AUTO; 205 state = ACERHDF_FAN_AUTO;
176 } 206 }
177 207
178 cmd = bios_cfg->fancmd[state]; 208 cmd = (state == ACERHDF_FAN_OFF) ? bios_cfg->cmd.cmd_off
209 : bios_cfg->cmd.cmd_auto;
179 fanstate = state; 210 fanstate = state;
180 211
181 ec_write(bios_cfg->fanreg, cmd); 212 ec_write(bios_cfg->fanreg, cmd);
@@ -408,7 +439,7 @@ struct thermal_cooling_device_ops acerhdf_cooling_ops = {
408}; 439};
409 440
410/* suspend / resume functionality */ 441/* suspend / resume functionality */
411static int acerhdf_suspend(struct platform_device *dev, pm_message_t state) 442static int acerhdf_suspend(struct device *dev)
412{ 443{
413 if (kernelmode) 444 if (kernelmode)
414 acerhdf_change_fanstate(ACERHDF_FAN_AUTO); 445 acerhdf_change_fanstate(ACERHDF_FAN_AUTO);
@@ -419,14 +450,6 @@ static int acerhdf_suspend(struct platform_device *dev, pm_message_t state)
419 return 0; 450 return 0;
420} 451}
421 452
422static int acerhdf_resume(struct platform_device *device)
423{
424 if (verbose)
425 pr_notice("resuming\n");
426
427 return 0;
428}
429
430static int __devinit acerhdf_probe(struct platform_device *device) 453static int __devinit acerhdf_probe(struct platform_device *device)
431{ 454{
432 return 0; 455 return 0;
@@ -437,15 +460,19 @@ static int acerhdf_remove(struct platform_device *device)
437 return 0; 460 return 0;
438} 461}
439 462
440struct platform_driver acerhdf_drv = { 463static struct dev_pm_ops acerhdf_pm_ops = {
464 .suspend = acerhdf_suspend,
465 .freeze = acerhdf_suspend,
466};
467
468static struct platform_driver acerhdf_driver = {
441 .driver = { 469 .driver = {
442 .name = "acerhdf", 470 .name = "acerhdf",
443 .owner = THIS_MODULE, 471 .owner = THIS_MODULE,
472 .pm = &acerhdf_pm_ops,
444 }, 473 },
445 .probe = acerhdf_probe, 474 .probe = acerhdf_probe,
446 .remove = acerhdf_remove, 475 .remove = acerhdf_remove,
447 .suspend = acerhdf_suspend,
448 .resume = acerhdf_resume,
449}; 476};
450 477
451 478
@@ -454,32 +481,40 @@ static int acerhdf_check_hardware(void)
454{ 481{
455 char const *vendor, *version, *product; 482 char const *vendor, *version, *product;
456 int i; 483 int i;
484 unsigned long prod_len = 0;
457 485
458 /* get BIOS data */ 486 /* get BIOS data */
459 vendor = dmi_get_system_info(DMI_SYS_VENDOR); 487 vendor = dmi_get_system_info(DMI_SYS_VENDOR);
460 version = dmi_get_system_info(DMI_BIOS_VERSION); 488 version = dmi_get_system_info(DMI_BIOS_VERSION);
461 product = dmi_get_system_info(DMI_PRODUCT_NAME); 489 product = dmi_get_system_info(DMI_PRODUCT_NAME);
462 490
491
463 pr_info("Acer Aspire One Fan driver, v.%s\n", DRV_VER); 492 pr_info("Acer Aspire One Fan driver, v.%s\n", DRV_VER);
464 493
465 if (!force_bios[0]) { 494 if (force_bios[0]) {
466 if (strncmp(product, "AO", 2)) {
467 pr_err("no Aspire One hardware found\n");
468 return -EINVAL;
469 }
470 } else {
471 pr_info("forcing BIOS version: %s\n", version);
472 version = force_bios; 495 version = force_bios;
496 pr_info("forcing BIOS version: %s\n", version);
497 kernelmode = 0;
498 }
499
500 if (force_product[0]) {
501 product = force_product;
502 pr_info("forcing BIOS product: %s\n", product);
473 kernelmode = 0; 503 kernelmode = 0;
474 } 504 }
475 505
506 prod_len = strlen(product);
507
476 if (verbose) 508 if (verbose)
477 pr_info("BIOS info: %s %s, product: %s\n", 509 pr_info("BIOS info: %s %s, product: %s\n",
478 vendor, version, product); 510 vendor, version, product);
479 511
480 /* search BIOS version and vendor in BIOS settings table */ 512 /* search BIOS version and vendor in BIOS settings table */
481 for (i = 0; bios_tbl[i].version[0]; i++) { 513 for (i = 0; bios_tbl[i].version[0]; i++) {
482 if (!strcmp(bios_tbl[i].vendor, vendor) && 514 if (strlen(bios_tbl[i].product) >= prod_len &&
515 !strncmp(bios_tbl[i].product, product,
516 strlen(bios_tbl[i].product)) &&
517 !strcmp(bios_tbl[i].vendor, vendor) &&
483 !strcmp(bios_tbl[i].version, version)) { 518 !strcmp(bios_tbl[i].version, version)) {
484 bios_cfg = &bios_tbl[i]; 519 bios_cfg = &bios_tbl[i];
485 break; 520 break;
@@ -487,8 +522,8 @@ static int acerhdf_check_hardware(void)
487 } 522 }
488 523
489 if (!bios_cfg) { 524 if (!bios_cfg) {
490 pr_err("unknown (unsupported) BIOS version %s/%s, " 525 pr_err("unknown (unsupported) BIOS version %s/%s/%s, "
491 "please report, aborting!\n", vendor, version); 526 "please report, aborting!\n", vendor, product, version);
492 return -EINVAL; 527 return -EINVAL;
493 } 528 }
494 529
@@ -509,7 +544,7 @@ static int acerhdf_register_platform(void)
509{ 544{
510 int err = 0; 545 int err = 0;
511 546
512 err = platform_driver_register(&acerhdf_drv); 547 err = platform_driver_register(&acerhdf_driver);
513 if (err) 548 if (err)
514 return err; 549 return err;
515 550
@@ -525,7 +560,7 @@ static void acerhdf_unregister_platform(void)
525 return; 560 return;
526 561
527 platform_device_del(acerhdf_dev); 562 platform_device_del(acerhdf_dev);
528 platform_driver_unregister(&acerhdf_drv); 563 platform_driver_unregister(&acerhdf_driver);
529} 564}
530 565
531static int acerhdf_register_thermal(void) 566static int acerhdf_register_thermal(void)