diff options
-rw-r--r-- | drivers/hwmon/applesmc.c | 241 |
1 files changed, 59 insertions, 182 deletions
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 1d7f8af..d4d6475 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -106,16 +106,6 @@ static const char* fan_speed_keys[] = { #define to_index(attr) (to_sensor_dev_attr(attr)->index) -/* Structure to be passed to DMI_MATCH function */ -struct dmi_match_data { -/* Indicates whether this computer has an accelerometer. */ - int accelerometer; -/* Indicates whether this computer has light sensors and keyboard backlight. */ - int light; -/* Indicates which temperature sensors set to use. */ - int temperature_set; -}; - /* Dynamic device node attributes */ struct applesmc_dev_attr { struct sensor_device_attribute sda; /* hwmon attributes */ @@ -146,6 +136,9 @@ static struct applesmc_registers { unsigned int temp_count; /* number of temperature registers */ unsigned int temp_begin; /* temperature lower index bound */ unsigned int temp_end; /* temperature upper index bound */ + int num_light_sensors; /* number of light sensors */ + bool has_accelerometer; /* has motion sensor */ + bool has_key_backlight; /* has keyboard backlight */ bool init_complete; /* true when fully initialized */ struct applesmc_entry *cache; /* cached key entries */ } smcreg = { @@ -161,12 +154,6 @@ static u8 backlight_state[2]; static struct device *hwmon_dev; static struct input_polled_dev *applesmc_idev; -/* Indicates whether this computer has an accelerometer. */ -static unsigned int applesmc_accelerometer; - -/* Indicates whether this computer has light sensors and keyboard backlight. */ -static unsigned int applesmc_light; - /* The number of fans handled by the driver */ static unsigned int fans_handled; @@ -433,6 +420,18 @@ static int applesmc_write_key(const char *key, const u8 *buffer, u8 len) return applesmc_write_entry(entry, buffer, len); } +static int applesmc_has_key(const char *key, bool *value) +{ + const struct applesmc_entry *entry; + + entry = applesmc_get_entry_by_key(key); + if (IS_ERR(entry) && PTR_ERR(entry) != -EINVAL) + return PTR_ERR(entry); + + *value = !IS_ERR(entry); + return 0; +} + /* * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). */ @@ -468,7 +467,7 @@ static void applesmc_device_init(void) int total; u8 buffer[2]; - if (!applesmc_accelerometer) + if (!smcreg.has_accelerometer) return; for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { @@ -506,6 +505,7 @@ static int applesmc_get_fan_count(void) static int applesmc_init_smcreg_try(void) { struct applesmc_registers *s = &smcreg; + bool left_light_sensor, right_light_sensor; int ret; if (s->init_complete) @@ -528,9 +528,27 @@ static int applesmc_init_smcreg_try(void) return ret; s->temp_count = s->temp_end - s->temp_begin; + ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor); + if (ret) + return ret; + ret = applesmc_has_key(LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor); + if (ret) + return ret; + ret = applesmc_has_key(MOTION_SENSOR_KEY, &s->has_accelerometer); + if (ret) + return ret; + ret = applesmc_has_key(BACKLIGHT_KEY, &s->has_key_backlight); + if (ret) + return ret; + + s->num_light_sensors = left_light_sensor + right_light_sensor; s->init_complete = true; - pr_info("key=%d temp=%d\n", s->key_count, s->temp_count); + pr_info("key=%d temp=%d acc=%d lux=%d kbd=%d\n", + s->key_count, s->temp_count, + s->has_accelerometer, + s->num_light_sensors, + s->has_key_backlight); return 0; } @@ -585,7 +603,7 @@ static int applesmc_probe(struct platform_device *dev) /* Synchronize device with memorized backlight state */ static int applesmc_pm_resume(struct device *dev) { - if (applesmc_light) + if (smcreg.has_key_backlight) applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); return 0; } @@ -1118,23 +1136,6 @@ static struct applesmc_node_group temp_group[] = { /* Module stuff */ /* - * applesmc_dmi_match - found a match. return one, short-circuiting the hunt. - */ -static int applesmc_dmi_match(const struct dmi_system_id *id) -{ - struct dmi_match_data* dmi_data = id->driver_data; - pr_info("%s detected:\n", id->ident); - applesmc_accelerometer = dmi_data->accelerometer; - pr_info(" - Model %s accelerometer\n", - applesmc_accelerometer ? "with" : "without"); - applesmc_light = dmi_data->light; - pr_info(" - Model %s light sensors and backlight\n", - applesmc_light ? "with" : "without"); - - return 1; -} - -/* * applesmc_destroy_nodes - remove files and free associated memory */ static void applesmc_destroy_nodes(struct applesmc_node_group *groups) @@ -1248,165 +1249,38 @@ static void applesmc_release_accelerometer(void) input_free_polled_device(applesmc_idev); sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); } - -static __initdata struct dmi_match_data applesmc_dmi_data[] = { -/* MacBook Pro: accelerometer, backlight and temperature set 0 */ - { .accelerometer = 1, .light = 1, .temperature_set = 0 }, -/* MacBook2: accelerometer and temperature set 1 */ - { .accelerometer = 1, .light = 0, .temperature_set = 1 }, -/* MacBook: accelerometer and temperature set 2 */ - { .accelerometer = 1, .light = 0, .temperature_set = 2 }, -/* MacMini: temperature set 3 */ - { .accelerometer = 0, .light = 0, .temperature_set = 3 }, -/* MacPro: temperature set 4 */ - { .accelerometer = 0, .light = 0, .temperature_set = 4 }, -/* iMac: temperature set 5 */ - { .accelerometer = 0, .light = 0, .temperature_set = 5 }, -/* MacBook3, MacBook4: accelerometer and temperature set 6 */ - { .accelerometer = 1, .light = 0, .temperature_set = 6 }, -/* MacBook Air: accelerometer, backlight and temperature set 7 */ - { .accelerometer = 1, .light = 1, .temperature_set = 7 }, -/* MacBook Pro 4: accelerometer, backlight and temperature set 8 */ - { .accelerometer = 1, .light = 1, .temperature_set = 8 }, -/* MacBook Pro 3: accelerometer, backlight and temperature set 9 */ - { .accelerometer = 1, .light = 1, .temperature_set = 9 }, -/* iMac 5: light sensor only, temperature set 10 */ - { .accelerometer = 0, .light = 0, .temperature_set = 10 }, -/* MacBook 5: accelerometer, backlight and temperature set 11 */ - { .accelerometer = 1, .light = 1, .temperature_set = 11 }, -/* MacBook Pro 5: accelerometer, backlight and temperature set 12 */ - { .accelerometer = 1, .light = 1, .temperature_set = 12 }, -/* iMac 8: light sensor only, temperature set 13 */ - { .accelerometer = 0, .light = 0, .temperature_set = 13 }, -/* iMac 6: light sensor only, temperature set 14 */ - { .accelerometer = 0, .light = 0, .temperature_set = 14 }, -/* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */ - { .accelerometer = 1, .light = 1, .temperature_set = 15 }, -/* MacPro3,1: temperature set 16 */ - { .accelerometer = 0, .light = 0, .temperature_set = 16 }, -/* iMac 9,1: light sensor only, temperature set 17 */ - { .accelerometer = 0, .light = 0, .temperature_set = 17 }, -/* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */ - { .accelerometer = 1, .light = 1, .temperature_set = 18 }, -/* MacBook Pro 5,3: accelerometer, backlight and temperature set 19 */ - { .accelerometer = 1, .light = 1, .temperature_set = 19 }, -/* MacBook Pro 5,4: accelerometer, backlight and temperature set 20 */ - { .accelerometer = 1, .light = 1, .temperature_set = 20 }, -/* MacBook Pro 6,2: accelerometer, backlight and temperature set 21 */ - { .accelerometer = 1, .light = 1, .temperature_set = 21 }, -/* MacBook Pro 7,1: accelerometer, backlight and temperature set 22 */ - { .accelerometer = 1, .light = 1, .temperature_set = 22 }, -/* MacBook Air 3,1: accelerometer, backlight and temperature set 23 */ - { .accelerometer = 0, .light = 0, .temperature_set = 23 }, -}; +static int applesmc_dmi_match(const struct dmi_system_id *id) +{ + return 1; +} /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ static __initdata struct dmi_system_id applesmc_whitelist[] = { - { applesmc_dmi_match, "Apple MacBook Air 3", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3") }, - &applesmc_dmi_data[23]}, - { applesmc_dmi_match, "Apple MacBook Air 2", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") }, - &applesmc_dmi_data[15]}, { applesmc_dmi_match, "Apple MacBook Air", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, - &applesmc_dmi_data[7]}, - { applesmc_dmi_match, "Apple MacBook Pro 7", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro7") }, - &applesmc_dmi_data[22]}, - { applesmc_dmi_match, "Apple MacBook Pro 5,4", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4") }, - &applesmc_dmi_data[20]}, - { applesmc_dmi_match, "Apple MacBook Pro 5,3", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3") }, - &applesmc_dmi_data[19]}, - { applesmc_dmi_match, "Apple MacBook Pro 6", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6") }, - &applesmc_dmi_data[21]}, - { applesmc_dmi_match, "Apple MacBook Pro 5", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") }, - &applesmc_dmi_data[12]}, - { applesmc_dmi_match, "Apple MacBook Pro 4", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") }, - &applesmc_dmi_data[8]}, - { applesmc_dmi_match, "Apple MacBook Pro 3", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") }, - &applesmc_dmi_data[9]}, - { applesmc_dmi_match, "Apple MacBook Pro 2,2", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") }, - &applesmc_dmi_data[18]}, + }, { applesmc_dmi_match, "Apple MacBook Pro", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, - &applesmc_dmi_data[0]}, - { applesmc_dmi_match, "Apple MacBook (v2)", { - DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), - DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") }, - &applesmc_dmi_data[1]}, - { applesmc_dmi_match, "Apple MacBook (v3)", { - DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), - DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") }, - &applesmc_dmi_data[6]}, - { applesmc_dmi_match, "Apple MacBook 4", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") }, - &applesmc_dmi_data[6]}, - { applesmc_dmi_match, "Apple MacBook 5", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") }, - &applesmc_dmi_data[11]}, + }, { applesmc_dmi_match, "Apple MacBook", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, - &applesmc_dmi_data[2]}, + }, { applesmc_dmi_match, "Apple Macmini", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, - &applesmc_dmi_data[3]}, - { applesmc_dmi_match, "Apple MacPro2", { - DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), - DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, - &applesmc_dmi_data[4]}, - { applesmc_dmi_match, "Apple MacPro3", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") }, - &applesmc_dmi_data[16]}, + }, { applesmc_dmi_match, "Apple MacPro", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, - &applesmc_dmi_data[4]}, - { applesmc_dmi_match, "Apple iMac 9,1", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") }, - &applesmc_dmi_data[17]}, - { applesmc_dmi_match, "Apple iMac 8", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") }, - &applesmc_dmi_data[13]}, - { applesmc_dmi_match, "Apple iMac 6", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") }, - &applesmc_dmi_data[14]}, - { applesmc_dmi_match, "Apple iMac 5", { - DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") }, - &applesmc_dmi_data[10]}, + }, { applesmc_dmi_match, "Apple iMac", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, - &applesmc_dmi_data[5]}, + }, { .ident = NULL } }; @@ -1476,18 +1350,20 @@ static int __init applesmc_init(void) if (ret) goto out_fans; - if (applesmc_accelerometer) { + if (smcreg.has_accelerometer) { ret = applesmc_create_accelerometer(); if (ret) goto out_temperature; } - if (applesmc_light) { + if (smcreg.num_light_sensors) { /* Add light sensor file */ ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr); if (ret) goto out_accelerometer; + } + if (smcreg.has_key_backlight) { /* Create the workqueue */ applesmc_led_wq = create_singlethread_workqueue("applesmc-led"); if (!applesmc_led_wq) { @@ -1512,16 +1388,16 @@ static int __init applesmc_init(void) return 0; out_light_ledclass: - if (applesmc_light) + if (smcreg.has_key_backlight) led_classdev_unregister(&applesmc_backlight); out_light_wq: - if (applesmc_light) + if (smcreg.has_key_backlight) destroy_workqueue(applesmc_led_wq); out_light_sysfs: - if (applesmc_light) + if (smcreg.num_light_sensors) sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr); out_accelerometer: - if (applesmc_accelerometer) + if (smcreg.has_accelerometer) applesmc_release_accelerometer(); out_temperature: applesmc_destroy_nodes(temp_group); @@ -1548,12 +1424,13 @@ out: static void __exit applesmc_exit(void) { hwmon_device_unregister(hwmon_dev); - if (applesmc_light) { + if (smcreg.has_key_backlight) { led_classdev_unregister(&applesmc_backlight); destroy_workqueue(applesmc_led_wq); - sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr); } - if (applesmc_accelerometer) + if (smcreg.num_light_sensors) + sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr); + if (smcreg.has_accelerometer) applesmc_release_accelerometer(); applesmc_destroy_nodes(temp_group); while (fans_handled) |