aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/acerhdf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/acerhdf.c')
-rw-r--r--drivers/platform/x86/acerhdf.c68
1 files changed, 49 insertions, 19 deletions
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index ea22591ee66f..505224225378 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -86,6 +86,7 @@ static unsigned int interval = 10;
86static unsigned int fanon = 60000; 86static unsigned int fanon = 60000;
87static unsigned int fanoff = 53000; 87static unsigned int fanoff = 53000;
88static unsigned int verbose; 88static unsigned int verbose;
89static unsigned int list_supported;
89static unsigned int fanstate = ACERHDF_FAN_AUTO; 90static unsigned int fanstate = ACERHDF_FAN_AUTO;
90static char force_bios[16]; 91static char force_bios[16];
91static char force_product[16]; 92static char force_product[16];
@@ -104,10 +105,12 @@ module_param(fanoff, uint, 0600);
104MODULE_PARM_DESC(fanoff, "Turn the fan off below this temperature"); 105MODULE_PARM_DESC(fanoff, "Turn the fan off below this temperature");
105module_param(verbose, uint, 0600); 106module_param(verbose, uint, 0600);
106MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); 107MODULE_PARM_DESC(verbose, "Enable verbose dmesg output");
108module_param(list_supported, uint, 0600);
109MODULE_PARM_DESC(list_supported, "List supported models and BIOS versions");
107module_param_string(force_bios, force_bios, 16, 0); 110module_param_string(force_bios, force_bios, 16, 0);
108MODULE_PARM_DESC(force_bios, "Force BIOS version and omit BIOS check"); 111MODULE_PARM_DESC(force_bios, "Pretend system has this known supported BIOS version");
109module_param_string(force_product, force_product, 16, 0); 112module_param_string(force_product, force_product, 16, 0);
110MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check"); 113MODULE_PARM_DESC(force_product, "Pretend system is this known supported model");
111 114
112/* 115/*
113 * cmd_off: to switch the fan completely off and check if the fan is off 116 * cmd_off: to switch the fan completely off and check if the fan is off
@@ -130,7 +133,7 @@ static const struct manualcmd mcmd = {
130 .moff = 0xff, 133 .moff = 0xff,
131}; 134};
132 135
133/* BIOS settings */ 136/* BIOS settings - only used during probe */
134struct bios_settings { 137struct bios_settings {
135 const char *vendor; 138 const char *vendor;
136 const char *product; 139 const char *product;
@@ -141,8 +144,18 @@ struct bios_settings {
141 int mcmd_enable; 144 int mcmd_enable;
142}; 145};
143 146
147/* This could be a daughter struct in the above, but not worth the redirect */
148struct ctrl_settings {
149 u8 fanreg;
150 u8 tempreg;
151 struct fancmd cmd;
152 int mcmd_enable;
153};
154
155static struct ctrl_settings ctrl_cfg __read_mostly;
156
144/* Register addresses and values for different BIOS versions */ 157/* Register addresses and values for different BIOS versions */
145static const struct bios_settings bios_tbl[] = { 158static const struct bios_settings bios_tbl[] __initconst = {
146 /* AOA110 */ 159 /* AOA110 */
147 {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00}, 0}, 160 {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00}, 0},
148 {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00}, 0}, 161 {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00}, 0},
@@ -233,6 +246,7 @@ static const struct bios_settings bios_tbl[] = {
233 {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00}, 0}, 246 {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00}, 0},
234 {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00}, 0}, 247 {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00}, 0},
235 {"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00}, 0}, 248 {"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00}, 0},
249 {"Gateway", "LT31", "v1.3307", 0x55, 0x58, {0x9e, 0x00}, 0},
236 /* Packard Bell */ 250 /* Packard Bell */
237 {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00}, 0}, 251 {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00}, 0},
238 {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00}, 0}, 252 {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00}, 0},
@@ -256,8 +270,6 @@ static const struct bios_settings bios_tbl[] = {
256 {"", "", "", 0, 0, {0, 0}, 0} 270 {"", "", "", 0, 0, {0, 0}, 0}
257}; 271};
258 272
259static const struct bios_settings *bios_cfg __read_mostly;
260
261/* 273/*
262 * this struct is used to instruct thermal layer to use bang_bang instead of 274 * this struct is used to instruct thermal layer to use bang_bang instead of
263 * default governor for acerhdf 275 * default governor for acerhdf
@@ -270,7 +282,7 @@ static int acerhdf_get_temp(int *temp)
270{ 282{
271 u8 read_temp; 283 u8 read_temp;
272 284
273 if (ec_read(bios_cfg->tempreg, &read_temp)) 285 if (ec_read(ctrl_cfg.tempreg, &read_temp))
274 return -EINVAL; 286 return -EINVAL;
275 287
276 *temp = read_temp * 1000; 288 *temp = read_temp * 1000;
@@ -282,10 +294,10 @@ static int acerhdf_get_fanstate(int *state)
282{ 294{
283 u8 fan; 295 u8 fan;
284 296
285 if (ec_read(bios_cfg->fanreg, &fan)) 297 if (ec_read(ctrl_cfg.fanreg, &fan))
286 return -EINVAL; 298 return -EINVAL;
287 299
288 if (fan != bios_cfg->cmd.cmd_off) 300 if (fan != ctrl_cfg.cmd.cmd_off)
289 *state = ACERHDF_FAN_AUTO; 301 *state = ACERHDF_FAN_AUTO;
290 else 302 else
291 *state = ACERHDF_FAN_OFF; 303 *state = ACERHDF_FAN_OFF;
@@ -306,13 +318,13 @@ static void acerhdf_change_fanstate(int state)
306 state = ACERHDF_FAN_AUTO; 318 state = ACERHDF_FAN_AUTO;
307 } 319 }
308 320
309 cmd = (state == ACERHDF_FAN_OFF) ? bios_cfg->cmd.cmd_off 321 cmd = (state == ACERHDF_FAN_OFF) ? ctrl_cfg.cmd.cmd_off
310 : bios_cfg->cmd.cmd_auto; 322 : ctrl_cfg.cmd.cmd_auto;
311 fanstate = state; 323 fanstate = state;
312 324
313 ec_write(bios_cfg->fanreg, cmd); 325 ec_write(ctrl_cfg.fanreg, cmd);
314 326
315 if (bios_cfg->mcmd_enable && state == ACERHDF_FAN_OFF) { 327 if (ctrl_cfg.mcmd_enable && state == ACERHDF_FAN_OFF) {
316 if (verbose) 328 if (verbose)
317 pr_notice("turning off fan manually\n"); 329 pr_notice("turning off fan manually\n");
318 ec_write(mcmd.mreg, mcmd.moff); 330 ec_write(mcmd.mreg, mcmd.moff);
@@ -615,10 +627,11 @@ static int str_starts_with(const char *str, const char *start)
615} 627}
616 628
617/* check hardware */ 629/* check hardware */
618static int acerhdf_check_hardware(void) 630static int __init acerhdf_check_hardware(void)
619{ 631{
620 char const *vendor, *version, *product; 632 char const *vendor, *version, *product;
621 const struct bios_settings *bt = NULL; 633 const struct bios_settings *bt = NULL;
634 int found = 0;
622 635
623 /* get BIOS data */ 636 /* get BIOS data */
624 vendor = dmi_get_system_info(DMI_SYS_VENDOR); 637 vendor = dmi_get_system_info(DMI_SYS_VENDOR);
@@ -632,6 +645,17 @@ static int acerhdf_check_hardware(void)
632 645
633 pr_info("Acer Aspire One Fan driver, v.%s\n", DRV_VER); 646 pr_info("Acer Aspire One Fan driver, v.%s\n", DRV_VER);
634 647
648 if (list_supported) {
649 pr_info("List of supported Manufacturer/Model/BIOS:\n");
650 pr_info("---------------------------------------------------\n");
651 for (bt = bios_tbl; bt->vendor[0]; bt++) {
652 pr_info("%-13s | %-17s | %-10s\n", bt->vendor,
653 bt->product, bt->version);
654 }
655 pr_info("---------------------------------------------------\n");
656 return -ECANCELED;
657 }
658
635 if (force_bios[0]) { 659 if (force_bios[0]) {
636 version = force_bios; 660 version = force_bios;
637 pr_info("forcing BIOS version: %s\n", version); 661 pr_info("forcing BIOS version: %s\n", version);
@@ -657,30 +681,36 @@ static int acerhdf_check_hardware(void)
657 if (str_starts_with(vendor, bt->vendor) && 681 if (str_starts_with(vendor, bt->vendor) &&
658 str_starts_with(product, bt->product) && 682 str_starts_with(product, bt->product) &&
659 str_starts_with(version, bt->version)) { 683 str_starts_with(version, bt->version)) {
660 bios_cfg = bt; 684 found = 1;
661 break; 685 break;
662 } 686 }
663 } 687 }
664 688
665 if (!bios_cfg) { 689 if (!found) {
666 pr_err("unknown (unsupported) BIOS version %s/%s/%s, please report, aborting!\n", 690 pr_err("unknown (unsupported) BIOS version %s/%s/%s, please report, aborting!\n",
667 vendor, product, version); 691 vendor, product, version);
668 return -EINVAL; 692 return -EINVAL;
669 } 693 }
670 694
695 /* Copy control settings from BIOS table before we free it. */
696 ctrl_cfg.fanreg = bt->fanreg;
697 ctrl_cfg.tempreg = bt->tempreg;
698 memcpy(&ctrl_cfg.cmd, &bt->cmd, sizeof(struct fancmd));
699 ctrl_cfg.mcmd_enable = bt->mcmd_enable;
700
671 /* 701 /*
672 * if started with kernel mode off, prevent the kernel from switching 702 * if started with kernel mode off, prevent the kernel from switching
673 * off the fan 703 * off the fan
674 */ 704 */
675 if (!kernelmode) { 705 if (!kernelmode) {
676 pr_notice("Fan control off, to enable do:\n"); 706 pr_notice("Fan control off, to enable do:\n");
677 pr_notice("echo -n \"enabled\" > /sys/class/thermal/thermal_zone0/mode\n"); 707 pr_notice("echo -n \"enabled\" > /sys/class/thermal/thermal_zoneN/mode # N=0,1,2...\n");
678 } 708 }
679 709
680 return 0; 710 return 0;
681} 711}
682 712
683static int acerhdf_register_platform(void) 713static int __init acerhdf_register_platform(void)
684{ 714{
685 int err = 0; 715 int err = 0;
686 716
@@ -712,7 +742,7 @@ static void acerhdf_unregister_platform(void)
712 platform_driver_unregister(&acerhdf_driver); 742 platform_driver_unregister(&acerhdf_driver);
713} 743}
714 744
715static int acerhdf_register_thermal(void) 745static int __init acerhdf_register_thermal(void)
716{ 746{
717 cl_dev = thermal_cooling_device_register("acerhdf-fan", NULL, 747 cl_dev = thermal_cooling_device_register("acerhdf-fan", NULL,
718 &acerhdf_cooling_ops); 748 &acerhdf_cooling_ops);