asus-laptop: set initial lcd state
[safe/jmp/linux-2.6] / drivers / platform / x86 / acerhdf.c
index aa298d6..7b2384d 100644 (file)
@@ -52,7 +52,7 @@
  */
 #undef START_IN_KERNEL_MODE
 
-#define DRV_VER "0.5.16"
+#define DRV_VER "0.5.22"
 
 /*
  * According to the Atom N270 datasheet,
@@ -61,7 +61,7 @@
  * measured by the on-die thermal monitor are within 0 <= Tj <= 90. So,
  * assume 89°C is critical temperature.
  */
-#define ACERHDF_TEMP_CRIT 89
+#define ACERHDF_TEMP_CRIT 89000
 #define ACERHDF_FAN_OFF 0
 #define ACERHDF_FAN_AUTO 1
 
@@ -69,7 +69,7 @@
  * No matter what value the user puts into the fanon variable, turn on the fan
  * at 80 degree Celsius to prevent hardware damage
  */
-#define ACERHDF_MAX_FANON 80
+#define ACERHDF_MAX_FANON 80000
 
 /*
  * Maximum interval between two temperature checks is 15 seconds, as the die
@@ -85,8 +85,8 @@ static int kernelmode;
 #endif
 
 static unsigned int interval = 10;
-static unsigned int fanon = 63;
-static unsigned int fanoff = 58;
+static unsigned int fanon = 63000;
+static unsigned int fanoff = 58000;
 static unsigned int verbose;
 static unsigned int fanstate = ACERHDF_FAN_AUTO;
 static char force_bios[16];
@@ -112,12 +112,14 @@ module_param_string(force_product, force_product, 16, 0);
 MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check");
 
 /*
- * cmd_off: to switch the fan completely off / to check if the fan is off
+ * cmd_off: to switch the fan completely off
+ * chk_off: to check if the fan is off
  *     cmd_auto: to set the BIOS in control of the fan. The BIOS regulates then
  *             the fan speed depending on the temperature
  */
 struct fancmd {
        u8 cmd_off;
+       u8 chk_off;
        u8 cmd_auto;
 };
 
@@ -134,28 +136,47 @@ struct bios_settings_t {
 /* Register addresses and values for different BIOS versions */
 static const struct bios_settings_t bios_tbl[] = {
        /* AOA110 */
-       {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00} },
-       {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00} },
-       {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0x00} },
-       {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0x00} },
-       {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0x00} },
-       {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x00} },
-       {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00} },
-       {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00} },
+       {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x1f, 0x00} },
+       {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x1f, 0x00} },
+       {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+       {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+       {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+       {"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0xaf, 0x00} },
+       {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x21, 0x00} },
+       {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x21, 0x00} },
+       {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x21, 0x00} },
        /* AOA150 */
-       {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x00} },
-       {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00} },
-       {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00} },
-       {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} },
-       {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} },
-       {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} },
-       /* special BIOS / other */
-       {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} },
-       {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} },
-       {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} },
-       {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} },
+       {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x20, 0x00} },
+       {"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x20, 0x00} },
+       {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x20, 0x00} },
+       {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x20, 0x00} },
+       {"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x20, 0x00} },
+       {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x20, 0x00} },
+       {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x20, 0x00} },
+       {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x20, 0x00} },
+       /* Acer 1410 */
+       {"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+       {"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+       /* Acer 1810xx */
+       {"Acer", "Aspire 1810TZ", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+       {"Acer", "Aspire 1810T", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+       {"Acer", "Aspire 1810T", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+       {"Acer", "Aspire 1810TZ", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+       /* Gateway */
+       {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} },
+       {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} },
+       {"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x10, 0x0f, 0x00} },
+       {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x10, 0x0f, 0x00} },
+       {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x10, 0x0f, 0x00} },
+       /* Packard Bell */
+       {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} },
+       {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} },
+       {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x21, 0x00} },
+       {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} },
+       {"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
+       {"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} },
        /* pewpew-terminator */
-       {"", "", "", 0, 0, {0, 0} }
+       {"", "", "", 0, 0, {0, 0, 0} }
 };
 
 static const struct bios_settings_t *bios_cfg __read_mostly;
@@ -167,7 +188,7 @@ static int acerhdf_get_temp(int *temp)
        if (ec_read(bios_cfg->tempreg, &read_temp))
                return -EINVAL;
 
-       *temp = read_temp;
+       *temp = read_temp * 1000;
 
        return 0;
 }
@@ -179,7 +200,7 @@ static int acerhdf_get_fanstate(int *state)
        if (ec_read(bios_cfg->fanreg, &fan))
                return -EINVAL;
 
-       if (fan != bios_cfg->cmd.cmd_off)
+       if (fan != bios_cfg->cmd.chk_off)
                *state = ACERHDF_FAN_AUTO;
        else
                *state = ACERHDF_FAN_OFF;
@@ -435,7 +456,7 @@ struct thermal_cooling_device_ops acerhdf_cooling_ops = {
 };
 
 /* suspend / resume functionality */
-static int acerhdf_suspend(struct platform_device *dev, pm_message_t state)
+static int acerhdf_suspend(struct device *dev)
 {
        if (kernelmode)
                acerhdf_change_fanstate(ACERHDF_FAN_AUTO);
@@ -446,14 +467,6 @@ static int acerhdf_suspend(struct platform_device *dev, pm_message_t state)
        return 0;
 }
 
-static int acerhdf_resume(struct platform_device *device)
-{
-       if (verbose)
-               pr_notice("resuming\n");
-
-       return 0;
-}
-
 static int __devinit acerhdf_probe(struct platform_device *device)
 {
        return 0;
@@ -464,24 +477,41 @@ static int acerhdf_remove(struct platform_device *device)
        return 0;
 }
 
+static const struct dev_pm_ops acerhdf_pm_ops = {
+       .suspend = acerhdf_suspend,
+       .freeze  = acerhdf_suspend,
+};
+
 static struct platform_driver acerhdf_driver = {
        .driver = {
-               .name = "acerhdf",
+               .name  = "acerhdf",
                .owner = THIS_MODULE,
+               .pm    = &acerhdf_pm_ops,
        },
        .probe = acerhdf_probe,
        .remove = acerhdf_remove,
-       .suspend = acerhdf_suspend,
-       .resume = acerhdf_resume,
 };
 
+/* checks if str begins with start */
+static int str_starts_with(const char *str, const char *start)
+{
+       unsigned long str_len = 0, start_len = 0;
+
+       str_len = strlen(str);
+       start_len = strlen(start);
+
+       if (str_len >= start_len &&
+                       !strncmp(str, start, start_len))
+               return 1;
+
+       return 0;
+}
 
 /* check hardware */
 static int acerhdf_check_hardware(void)
 {
        char const *vendor, *version, *product;
-       int i;
-       unsigned long prod_len = 0;
+       const struct bios_settings_t *bt = NULL;
 
        /* get BIOS data */
        vendor  = dmi_get_system_info(DMI_SYS_VENDOR);
@@ -503,20 +533,20 @@ static int acerhdf_check_hardware(void)
                kernelmode = 0;
        }
 
-       prod_len = strlen(product);
-
        if (verbose)
                pr_info("BIOS info: %s %s, product: %s\n",
                        vendor, version, product);
 
        /* search BIOS version and vendor in BIOS settings table */
-       for (i = 0; bios_tbl[i].version[0]; i++) {
-               if (strlen(bios_tbl[i].product) >= prod_len &&
-                   !strncmp(bios_tbl[i].product, product,
-                          strlen(bios_tbl[i].product)) &&
-                   !strcmp(bios_tbl[i].vendor, vendor) &&
-                   !strcmp(bios_tbl[i].version, version)) {
-                       bios_cfg = &bios_tbl[i];
+       for (bt = bios_tbl; bt->vendor[0]; bt++) {
+               /*
+                * check if actual hardware BIOS vendor, product and version
+                * IDs start with the strings of BIOS table entry
+                */
+               if (str_starts_with(vendor, bt->vendor) &&
+                               str_starts_with(product, bt->product) &&
+                               str_starts_with(version, bt->version)) {
+                       bios_cfg = bt;
                        break;
                }
        }
@@ -629,9 +659,14 @@ static void __exit acerhdf_exit(void)
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Peter Feuerer");
 MODULE_DESCRIPTION("Aspire One temperature and fan driver");
-MODULE_ALIAS("dmi:*:*Acer*:*:");
-MODULE_ALIAS("dmi:*:*Gateway*:*:");
-MODULE_ALIAS("dmi:*:*Packard Bell*:*:");
+MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:");
+MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1410*:");
+MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1810*:");
+MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:");
+MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:");
+MODULE_ALIAS("dmi:*:*Packard Bell*:pnAOA*:");
+MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOA*:");
+MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOTMU*:");
 
 module_init(acerhdf_init);
 module_exit(acerhdf_exit);