aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/acerhdf.c
diff options
context:
space:
mode:
authorPeter Feuerer <peter@piie.net>2009-08-06 18:57:52 -0400
committerLen Brown <len.brown@intel.com>2009-09-19 01:49:25 -0400
commitded0cdfc6a7673916b0878c32fa8ba566b4f8cdb (patch)
treef9c8703d05fa95c56147fe11ec81207990c9d5b0 /drivers/platform/x86/acerhdf.c
parent1e23502cc57cef33455ac7cb9111e3c6d991a894 (diff)
acerhdf: fix fan control for AOA150 model
- Apply Borislav Petkov's patch (convert the fancmd[] array to a real struct thus disambiguating command handling and making code more readable.) - Add BIOS product to BIOS table as AOA110 and AOA150 have different register values - Add force_product parameter to allow forcing different product - fix linker warning caused by "acerhdf_drv" not being named "acerhdf_driver" Signed-off-by: Peter Feuerer <peter@piie.net> Cc: Andreas Mohr <andi@lisas.de> Acked-by: Borislav Petkov <petkovbb@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/platform/x86/acerhdf.c')
-rw-r--r--drivers/platform/x86/acerhdf.c97
1 files changed, 66 insertions, 31 deletions
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index bdfee177eefb..aa298d6ea371 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.16"
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,58 @@ 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.3308", 0x55, 0x58, {0x21, 0x00} },
129 {"Acer", "v0.3310", 0x55, 0x58, {0x21, 0x00} }, 143 {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00} },
130 {"Gateway", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, 144 {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00} },
131 {"Packard Bell", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, 145 /* AOA150 */
132 {"", "", 0, 0, {0, 0} } 146 {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x00} },
147 {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00} },
148 {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00} },
149 {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} },
150 {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} },
151 {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} },
152 /* special BIOS / other */
153 {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} },
154 {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} },
155 {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} },
156 {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} },
157 /* pewpew-terminator */
158 {"", "", "", 0, 0, {0, 0} }
133}; 159};
134 160
135static const struct bios_settings_t *bios_cfg __read_mostly; 161static const struct bios_settings_t *bios_cfg __read_mostly;
136 162
137
138static int acerhdf_get_temp(int *temp) 163static int acerhdf_get_temp(int *temp)
139{ 164{
140 u8 read_temp; 165 u8 read_temp;
@@ -150,13 +175,14 @@ static int acerhdf_get_temp(int *temp)
150static int acerhdf_get_fanstate(int *state) 175static int acerhdf_get_fanstate(int *state)
151{ 176{
152 u8 fan; 177 u8 fan;
153 bool tmp;
154 178
155 if (ec_read(bios_cfg->fanreg, &fan)) 179 if (ec_read(bios_cfg->fanreg, &fan))
156 return -EINVAL; 180 return -EINVAL;
157 181
158 tmp = (fan == bios_cfg->fancmd[ACERHDF_FAN_OFF]); 182 if (fan != bios_cfg->cmd.cmd_off)
159 *state = tmp ? ACERHDF_FAN_OFF : ACERHDF_FAN_AUTO; 183 *state = ACERHDF_FAN_AUTO;
184 else
185 *state = ACERHDF_FAN_OFF;
160 186
161 return 0; 187 return 0;
162} 188}
@@ -175,7 +201,8 @@ static void acerhdf_change_fanstate(int state)
175 state = ACERHDF_FAN_AUTO; 201 state = ACERHDF_FAN_AUTO;
176 } 202 }
177 203
178 cmd = bios_cfg->fancmd[state]; 204 cmd = (state == ACERHDF_FAN_OFF) ? bios_cfg->cmd.cmd_off
205 : bios_cfg->cmd.cmd_auto;
179 fanstate = state; 206 fanstate = state;
180 207
181 ec_write(bios_cfg->fanreg, cmd); 208 ec_write(bios_cfg->fanreg, cmd);
@@ -437,7 +464,7 @@ static int acerhdf_remove(struct platform_device *device)
437 return 0; 464 return 0;
438} 465}
439 466
440struct platform_driver acerhdf_drv = { 467static struct platform_driver acerhdf_driver = {
441 .driver = { 468 .driver = {
442 .name = "acerhdf", 469 .name = "acerhdf",
443 .owner = THIS_MODULE, 470 .owner = THIS_MODULE,
@@ -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);
473 kernelmode = 0; 497 kernelmode = 0;
474 } 498 }
475 499
500 if (force_product[0]) {
501 product = force_product;
502 pr_info("forcing BIOS product: %s\n", product);
503 kernelmode = 0;
504 }
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)