2 * drivers/hwmon/applesmc.c - driver for Apple's SMC (accelerometer, temperature
3 * sensors, fan control, keyboard backlight control) used in Intel-based Apple
6 * Copyright (C) 2007 Nicolas Boichat <nicolas@boichat.ch>
8 * Based on hdaps.c driver:
9 * Copyright (C) 2005 Robert Love <rml@novell.com>
10 * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com>
12 * Fan control based on smcFanControl:
13 * Copyright (C) 2006 Hendrik Holtmann <holtmann@mac.com>
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License v2 as published by the
17 * Free Software Foundation.
19 * This program is distributed in the hope that it will be useful, but WITHOUT
20 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
24 * You should have received a copy of the GNU General Public License along with
25 * this program; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
29 #include <linux/delay.h>
30 #include <linux/platform_device.h>
31 #include <linux/input-polldev.h>
32 #include <linux/kernel.h>
33 #include <linux/module.h>
34 #include <linux/timer.h>
35 #include <linux/dmi.h>
36 #include <linux/mutex.h>
37 #include <linux/hwmon-sysfs.h>
39 #include <linux/leds.h>
40 #include <linux/hwmon.h>
41 #include <linux/workqueue.h>
43 /* data port used by Apple SMC */
44 #define APPLESMC_DATA_PORT 0x300
45 /* command/status port used by Apple SMC */
46 #define APPLESMC_CMD_PORT 0x304
48 #define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
50 #define APPLESMC_MAX_DATA_LENGTH 32
52 #define APPLESMC_MIN_WAIT 0x0040
53 #define APPLESMC_MAX_WAIT 0x8000
55 #define APPLESMC_STATUS_MASK 0x0f
56 #define APPLESMC_READ_CMD 0x10
57 #define APPLESMC_WRITE_CMD 0x11
58 #define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12
59 #define APPLESMC_GET_KEY_TYPE_CMD 0x13
61 #define KEY_COUNT_KEY "#KEY" /* r-o ui32 */
63 #define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6-10 bytes) */
64 #define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6-10 bytes) */
65 #define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */
67 #define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */
69 #define MOTION_SENSOR_X_KEY "MO_X" /* r-o sp78 (2 bytes) */
70 #define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o sp78 (2 bytes) */
71 #define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o sp78 (2 bytes) */
72 #define MOTION_SENSOR_KEY "MOCN" /* r/w ui16 */
74 #define FANS_COUNT "FNum" /* r-o ui8 */
75 #define FANS_MANUAL "FS! " /* r-w ui16 */
76 #define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */
77 #define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 (2 bytes) */
78 #define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 (2 bytes) */
79 #define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 (2 bytes) */
80 #define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */
81 #define FAN_POSITION "F0ID" /* r-o char[16] */
84 * Temperature sensors keys (sp78 - 2 bytes).
86 static const char* temperature_sensors_sets[][36] = {
87 /* Set 0: Macbook Pro */
88 { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
89 "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
90 /* Set 1: Macbook2 set */
91 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "TTF0", "Th0H",
92 "Th0S", "Th1H", NULL },
93 /* Set 2: Macbook set */
94 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S",
95 "Th1H", "Ts0P", NULL },
96 /* Set 3: Macmini set */
97 { "TC0D", "TC0P", NULL },
98 /* Set 4: Mac Pro (2 x Quad-Core) */
99 { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
100 "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P",
101 "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S",
102 "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P",
103 "TM9S", "TN0H", "TS0C", NULL },
105 { "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P",
107 /* Set 6: Macbook3 set */
108 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H",
109 "Th0S", "Th1H", NULL },
110 /* Set 7: Macbook Air */
111 { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TC0P", "TCFP",
112 "TTF0", "TW0P", "Th0H", "Tp0P", "TpFP", "Ts0P", "Ts0S", NULL },
113 /* Set 8: Macbook Pro 4,1 (Penryn) */
114 { "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", "Th0H",
115 "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
116 /* Set 9: Macbook Pro 3,1 (Santa Rosa) */
117 { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P",
118 "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
119 /* Set 10: iMac 5,1 */
120 { "TA0P", "TC0D", "TC0P", "TG0D", "TH0P", "TO0P", "Tm0P", NULL },
123 /* List of keys used to read/write fan speeds */
124 static const char* fan_speed_keys[] = {
132 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
133 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
135 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
136 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
137 #define APPLESMC_INPUT_FLAT 4
143 /* Structure to be passed to DMI_MATCH function */
144 struct dmi_match_data {
145 /* Indicates whether this computer has an accelerometer. */
147 /* Indicates whether this computer has light sensors and keyboard backlight. */
149 /* Indicates which temperature sensors set to use. */
153 static const int debug;
154 static struct platform_device *pdev;
157 static struct device *hwmon_dev;
158 static struct input_polled_dev *applesmc_idev;
160 /* Indicates whether this computer has an accelerometer. */
161 static unsigned int applesmc_accelerometer;
163 /* Indicates whether this computer has light sensors and keyboard backlight. */
164 static unsigned int applesmc_light;
166 /* Indicates which temperature sensors set to use. */
167 static unsigned int applesmc_temperature_set;
169 static DEFINE_MUTEX(applesmc_lock);
172 * Last index written to key_at_index sysfs file, and value to use for all other
173 * key_at_index_* sysfs files.
175 static unsigned int key_at_index;
177 static struct workqueue_struct *applesmc_led_wq;
180 * __wait_status - Wait up to 32ms for the status port to get a certain value
181 * (masked with 0x0f), returning zero if the value is obtained. Callers must
182 * hold applesmc_lock.
184 static int __wait_status(u8 val)
188 val = val & APPLESMC_STATUS_MASK;
190 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
192 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
195 "Waited %d us for status %x\n",
196 2 * us - APPLESMC_MIN_WAIT, val);
201 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
202 val, inb(APPLESMC_CMD_PORT));
208 * special treatment of command port - on newer macbooks, it seems necessary
209 * to resend the command byte before polling the status again. Callers must
210 * hold applesmc_lock.
212 static int send_command(u8 cmd)
215 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
216 outb(cmd, APPLESMC_CMD_PORT);
218 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
221 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
222 cmd, inb(APPLESMC_CMD_PORT));
227 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
228 * Returns zero on success or a negative error on failure. Callers must
229 * hold applesmc_lock.
231 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
235 if (len > APPLESMC_MAX_DATA_LENGTH) {
236 printk(KERN_ERR "applesmc_read_key: cannot read more than "
237 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
241 if (send_command(APPLESMC_READ_CMD))
244 for (i = 0; i < 4; i++) {
245 outb(key[i], APPLESMC_DATA_PORT);
246 if (__wait_status(0x04))
250 printk(KERN_DEBUG "<%s", key);
252 outb(len, APPLESMC_DATA_PORT);
254 printk(KERN_DEBUG ">%x", len);
256 for (i = 0; i < len; i++) {
257 if (__wait_status(0x05))
259 buffer[i] = inb(APPLESMC_DATA_PORT);
261 printk(KERN_DEBUG "<%x", buffer[i]);
264 printk(KERN_DEBUG "\n");
270 * applesmc_write_key - writes len bytes from buffer to a given key.
271 * Returns zero on success or a negative error on failure. Callers must
272 * hold applesmc_lock.
274 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
278 if (len > APPLESMC_MAX_DATA_LENGTH) {
279 printk(KERN_ERR "applesmc_write_key: cannot write more than "
280 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
284 if (send_command(APPLESMC_WRITE_CMD))
287 for (i = 0; i < 4; i++) {
288 outb(key[i], APPLESMC_DATA_PORT);
289 if (__wait_status(0x04))
293 outb(len, APPLESMC_DATA_PORT);
295 for (i = 0; i < len; i++) {
296 if (__wait_status(0x04))
298 outb(buffer[i], APPLESMC_DATA_PORT);
305 * applesmc_get_key_at_index - get key at index, and put the result in key
306 * (char[6]). Returns zero on success or a negative error on failure. Callers
307 * must hold applesmc_lock.
309 static int applesmc_get_key_at_index(int index, char* key)
313 readkey[0] = index >> 24;
314 readkey[1] = index >> 16;
315 readkey[2] = index >> 8;
318 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
321 for (i = 0; i < 4; i++) {
322 outb(readkey[i], APPLESMC_DATA_PORT);
323 if (__wait_status(0x04))
327 outb(4, APPLESMC_DATA_PORT);
329 for (i = 0; i < 4; i++) {
330 if (__wait_status(0x05))
332 key[i] = inb(APPLESMC_DATA_PORT);
340 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
341 * Returns zero on success or a negative error on failure. Callers must
342 * hold applesmc_lock.
344 static int applesmc_get_key_type(char* key, char* type)
348 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
351 for (i = 0; i < 4; i++) {
352 outb(key[i], APPLESMC_DATA_PORT);
353 if (__wait_status(0x04))
357 outb(6, APPLESMC_DATA_PORT);
359 for (i = 0; i < 6; i++) {
360 if (__wait_status(0x05))
362 type[i] = inb(APPLESMC_DATA_PORT);
370 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
371 * hold applesmc_lock.
373 static int applesmc_read_motion_sensor(int index, s16* value)
380 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
383 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
386 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
392 *value = ((s16)buffer[0] << 8) | buffer[1];
398 * applesmc_device_init - initialize the accelerometer. Returns zero on success
399 * and negative error code on failure. Can sleep.
401 static int applesmc_device_init(void)
403 int total, ret = -ENXIO;
406 if (!applesmc_accelerometer)
409 mutex_lock(&applesmc_lock);
411 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
413 printk(KERN_DEBUG "applesmc try %d\n", total);
414 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
415 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
416 if (total == INIT_TIMEOUT_MSECS) {
417 printk(KERN_DEBUG "applesmc: device has"
418 " already been initialized"
419 " (0x%02x, 0x%02x).\n",
420 buffer[0], buffer[1]);
422 printk(KERN_DEBUG "applesmc: device"
423 " successfully initialized"
424 " (0x%02x, 0x%02x).\n",
425 buffer[0], buffer[1]);
432 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
433 msleep(INIT_WAIT_MSECS);
436 printk(KERN_WARNING "applesmc: failed to init the device\n");
439 mutex_unlock(&applesmc_lock);
444 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
447 static int applesmc_get_fan_count(void)
452 mutex_lock(&applesmc_lock);
454 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
456 mutex_unlock(&applesmc_lock);
463 /* Device model stuff */
464 static int applesmc_probe(struct platform_device *dev)
468 ret = applesmc_device_init();
472 printk(KERN_INFO "applesmc: device successfully initialized.\n");
476 static int applesmc_resume(struct platform_device *dev)
478 return applesmc_device_init();
481 static struct platform_driver applesmc_driver = {
482 .probe = applesmc_probe,
483 .resume = applesmc_resume,
486 .owner = THIS_MODULE,
491 * applesmc_calibrate - Set our "resting" values. Callers must
492 * hold applesmc_lock.
494 static void applesmc_calibrate(void)
496 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
497 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
501 static void applesmc_idev_poll(struct input_polled_dev *dev)
503 struct input_dev *idev = dev->input;
506 mutex_lock(&applesmc_lock);
508 if (applesmc_read_motion_sensor(SENSOR_X, &x))
510 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
514 input_report_abs(idev, ABS_X, x - rest_x);
515 input_report_abs(idev, ABS_Y, y - rest_y);
519 mutex_unlock(&applesmc_lock);
524 static ssize_t applesmc_name_show(struct device *dev,
525 struct device_attribute *attr, char *buf)
527 return snprintf(buf, PAGE_SIZE, "applesmc\n");
530 static ssize_t applesmc_position_show(struct device *dev,
531 struct device_attribute *attr, char *buf)
536 mutex_lock(&applesmc_lock);
538 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
541 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
544 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
549 mutex_unlock(&applesmc_lock);
553 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
556 static ssize_t applesmc_light_show(struct device *dev,
557 struct device_attribute *attr, char *sysfsbuf)
559 static int data_length;
561 u8 left = 0, right = 0;
562 u8 buffer[10], query[6];
564 mutex_lock(&applesmc_lock);
567 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
570 data_length = clamp_val(query[0], 0, 10);
571 printk(KERN_INFO "applesmc: light sensor data length set to "
572 "%d\n", data_length);
575 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
579 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
583 mutex_unlock(&applesmc_lock);
587 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
590 /* Displays degree Celsius * 1000 */
591 static ssize_t applesmc_show_temperature(struct device *dev,
592 struct device_attribute *devattr, char *sysfsbuf)
597 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
599 temperature_sensors_sets[applesmc_temperature_set][attr->index];
601 mutex_lock(&applesmc_lock);
603 ret = applesmc_read_key(key, buffer, 2);
604 temp = buffer[0]*1000;
605 temp += (buffer[1] >> 6) * 250;
607 mutex_unlock(&applesmc_lock);
612 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
615 static ssize_t applesmc_show_fan_speed(struct device *dev,
616 struct device_attribute *attr, char *sysfsbuf)
619 unsigned int speed = 0;
622 struct sensor_device_attribute_2 *sensor_attr =
623 to_sensor_dev_attr_2(attr);
625 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
626 newkey[1] = '0' + sensor_attr->index;
627 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
628 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
631 mutex_lock(&applesmc_lock);
633 ret = applesmc_read_key(newkey, buffer, 2);
634 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
636 mutex_unlock(&applesmc_lock);
640 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
643 static ssize_t applesmc_store_fan_speed(struct device *dev,
644 struct device_attribute *attr,
645 const char *sysfsbuf, size_t count)
651 struct sensor_device_attribute_2 *sensor_attr =
652 to_sensor_dev_attr_2(attr);
654 speed = simple_strtoul(sysfsbuf, NULL, 10);
656 if (speed > 0x4000) /* Bigger than a 14-bit value */
659 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
660 newkey[1] = '0' + sensor_attr->index;
661 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
662 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
665 mutex_lock(&applesmc_lock);
667 buffer[0] = (speed >> 6) & 0xff;
668 buffer[1] = (speed << 2) & 0xff;
669 ret = applesmc_write_key(newkey, buffer, 2);
671 mutex_unlock(&applesmc_lock);
678 static ssize_t applesmc_show_fan_manual(struct device *dev,
679 struct device_attribute *devattr, char *sysfsbuf)
684 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
686 mutex_lock(&applesmc_lock);
688 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
689 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
691 mutex_unlock(&applesmc_lock);
695 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
698 static ssize_t applesmc_store_fan_manual(struct device *dev,
699 struct device_attribute *devattr,
700 const char *sysfsbuf, size_t count)
706 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
708 input = simple_strtoul(sysfsbuf, NULL, 10);
710 mutex_lock(&applesmc_lock);
712 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
713 val = (buffer[0] << 8 | buffer[1]);
718 val = val | (0x01 << attr->index);
720 val = val & ~(0x01 << attr->index);
722 buffer[0] = (val >> 8) & 0xFF;
723 buffer[1] = val & 0xFF;
725 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
728 mutex_unlock(&applesmc_lock);
735 static ssize_t applesmc_show_fan_position(struct device *dev,
736 struct device_attribute *attr, char *sysfsbuf)
741 struct sensor_device_attribute_2 *sensor_attr =
742 to_sensor_dev_attr_2(attr);
744 newkey[0] = FAN_POSITION[0];
745 newkey[1] = '0' + sensor_attr->index;
746 newkey[2] = FAN_POSITION[2];
747 newkey[3] = FAN_POSITION[3];
750 mutex_lock(&applesmc_lock);
752 ret = applesmc_read_key(newkey, buffer, 16);
755 mutex_unlock(&applesmc_lock);
759 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
762 static ssize_t applesmc_calibrate_show(struct device *dev,
763 struct device_attribute *attr, char *sysfsbuf)
765 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
768 static ssize_t applesmc_calibrate_store(struct device *dev,
769 struct device_attribute *attr, const char *sysfsbuf, size_t count)
771 mutex_lock(&applesmc_lock);
772 applesmc_calibrate();
773 mutex_unlock(&applesmc_lock);
778 /* Store the next backlight value to be written by the work */
779 static unsigned int backlight_value;
781 static void applesmc_backlight_set(struct work_struct *work)
785 mutex_lock(&applesmc_lock);
786 buffer[0] = backlight_value;
788 applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
789 mutex_unlock(&applesmc_lock);
791 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
793 static void applesmc_brightness_set(struct led_classdev *led_cdev,
794 enum led_brightness value)
798 backlight_value = value;
799 ret = queue_work(applesmc_led_wq, &backlight_work);
802 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
805 static ssize_t applesmc_key_count_show(struct device *dev,
806 struct device_attribute *attr, char *sysfsbuf)
812 mutex_lock(&applesmc_lock);
814 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
815 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
816 ((u32)buffer[2]<<8) + buffer[3];
818 mutex_unlock(&applesmc_lock);
822 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
825 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
826 struct device_attribute *attr, char *sysfsbuf)
832 mutex_lock(&applesmc_lock);
834 ret = applesmc_get_key_at_index(key_at_index, key);
836 if (ret || !key[0]) {
837 mutex_unlock(&applesmc_lock);
842 ret = applesmc_get_key_type(key, info);
845 mutex_unlock(&applesmc_lock);
851 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
852 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
854 ret = applesmc_read_key(key, sysfsbuf, info[0]);
856 mutex_unlock(&applesmc_lock);
865 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
866 struct device_attribute *attr, char *sysfsbuf)
872 mutex_lock(&applesmc_lock);
874 ret = applesmc_get_key_at_index(key_at_index, key);
876 if (ret || !key[0]) {
877 mutex_unlock(&applesmc_lock);
882 ret = applesmc_get_key_type(key, info);
884 mutex_unlock(&applesmc_lock);
887 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
892 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
893 struct device_attribute *attr, char *sysfsbuf)
899 mutex_lock(&applesmc_lock);
901 ret = applesmc_get_key_at_index(key_at_index, key);
903 if (ret || !key[0]) {
904 mutex_unlock(&applesmc_lock);
909 ret = applesmc_get_key_type(key, info);
911 mutex_unlock(&applesmc_lock);
914 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
919 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
920 struct device_attribute *attr, char *sysfsbuf)
925 mutex_lock(&applesmc_lock);
927 ret = applesmc_get_key_at_index(key_at_index, key);
929 mutex_unlock(&applesmc_lock);
932 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
937 static ssize_t applesmc_key_at_index_show(struct device *dev,
938 struct device_attribute *attr, char *sysfsbuf)
940 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
943 static ssize_t applesmc_key_at_index_store(struct device *dev,
944 struct device_attribute *attr, const char *sysfsbuf, size_t count)
946 mutex_lock(&applesmc_lock);
948 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
950 mutex_unlock(&applesmc_lock);
955 static struct led_classdev applesmc_backlight = {
956 .name = "smc::kbd_backlight",
957 .default_trigger = "nand-disk",
958 .brightness_set = applesmc_brightness_set,
961 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
963 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
964 static DEVICE_ATTR(calibrate, 0644,
965 applesmc_calibrate_show, applesmc_calibrate_store);
967 static struct attribute *accelerometer_attributes[] = {
968 &dev_attr_position.attr,
969 &dev_attr_calibrate.attr,
973 static const struct attribute_group accelerometer_attributes_group =
974 { .attrs = accelerometer_attributes };
976 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
978 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
979 static DEVICE_ATTR(key_at_index, 0644,
980 applesmc_key_at_index_show, applesmc_key_at_index_store);
981 static DEVICE_ATTR(key_at_index_name, 0444,
982 applesmc_key_at_index_name_show, NULL);
983 static DEVICE_ATTR(key_at_index_type, 0444,
984 applesmc_key_at_index_type_show, NULL);
985 static DEVICE_ATTR(key_at_index_data_length, 0444,
986 applesmc_key_at_index_data_length_show, NULL);
987 static DEVICE_ATTR(key_at_index_data, 0444,
988 applesmc_key_at_index_read_show, NULL);
990 static struct attribute *key_enumeration_attributes[] = {
991 &dev_attr_key_count.attr,
992 &dev_attr_key_at_index.attr,
993 &dev_attr_key_at_index_name.attr,
994 &dev_attr_key_at_index_type.attr,
995 &dev_attr_key_at_index_data_length.attr,
996 &dev_attr_key_at_index_data.attr,
1000 static const struct attribute_group key_enumeration_group =
1001 { .attrs = key_enumeration_attributes };
1004 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1005 * - show actual speed
1006 * - show/store minimum speed
1007 * - show maximum speed
1009 * - show/store target speed
1010 * - show/store manual mode
1012 #define sysfs_fan_speeds_offset(offset) \
1013 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1014 applesmc_show_fan_speed, NULL, 0, offset-1); \
1016 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1017 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1019 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1020 applesmc_show_fan_speed, NULL, 2, offset-1); \
1022 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1023 applesmc_show_fan_speed, NULL, 3, offset-1); \
1025 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1026 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1028 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1029 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1031 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1032 applesmc_show_fan_position, NULL, offset-1); \
1034 static struct attribute *fan##offset##_attributes[] = { \
1035 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1036 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1037 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1038 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1039 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1040 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1041 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1046 * Create the needed functions for each fan using the macro defined above
1047 * (4 fans are supported)
1049 sysfs_fan_speeds_offset(1);
1050 sysfs_fan_speeds_offset(2);
1051 sysfs_fan_speeds_offset(3);
1052 sysfs_fan_speeds_offset(4);
1054 static const struct attribute_group fan_attribute_groups[] = {
1055 { .attrs = fan1_attributes },
1056 { .attrs = fan2_attributes },
1057 { .attrs = fan3_attributes },
1058 { .attrs = fan4_attributes },
1062 * Temperature sensors sysfs entries.
1064 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1065 applesmc_show_temperature, NULL, 0);
1066 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1067 applesmc_show_temperature, NULL, 1);
1068 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1069 applesmc_show_temperature, NULL, 2);
1070 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1071 applesmc_show_temperature, NULL, 3);
1072 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1073 applesmc_show_temperature, NULL, 4);
1074 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1075 applesmc_show_temperature, NULL, 5);
1076 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1077 applesmc_show_temperature, NULL, 6);
1078 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1079 applesmc_show_temperature, NULL, 7);
1080 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1081 applesmc_show_temperature, NULL, 8);
1082 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1083 applesmc_show_temperature, NULL, 9);
1084 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1085 applesmc_show_temperature, NULL, 10);
1086 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1087 applesmc_show_temperature, NULL, 11);
1088 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1089 applesmc_show_temperature, NULL, 12);
1090 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1091 applesmc_show_temperature, NULL, 13);
1092 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1093 applesmc_show_temperature, NULL, 14);
1094 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1095 applesmc_show_temperature, NULL, 15);
1096 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1097 applesmc_show_temperature, NULL, 16);
1098 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1099 applesmc_show_temperature, NULL, 17);
1100 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1101 applesmc_show_temperature, NULL, 18);
1102 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1103 applesmc_show_temperature, NULL, 19);
1104 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1105 applesmc_show_temperature, NULL, 20);
1106 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1107 applesmc_show_temperature, NULL, 21);
1108 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1109 applesmc_show_temperature, NULL, 22);
1110 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1111 applesmc_show_temperature, NULL, 23);
1112 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1113 applesmc_show_temperature, NULL, 24);
1114 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1115 applesmc_show_temperature, NULL, 25);
1116 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1117 applesmc_show_temperature, NULL, 26);
1118 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1119 applesmc_show_temperature, NULL, 27);
1120 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1121 applesmc_show_temperature, NULL, 28);
1122 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1123 applesmc_show_temperature, NULL, 29);
1124 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1125 applesmc_show_temperature, NULL, 30);
1126 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1127 applesmc_show_temperature, NULL, 31);
1128 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1129 applesmc_show_temperature, NULL, 32);
1130 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1131 applesmc_show_temperature, NULL, 33);
1132 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1133 applesmc_show_temperature, NULL, 34);
1135 static struct attribute *temperature_attributes[] = {
1136 &sensor_dev_attr_temp1_input.dev_attr.attr,
1137 &sensor_dev_attr_temp2_input.dev_attr.attr,
1138 &sensor_dev_attr_temp3_input.dev_attr.attr,
1139 &sensor_dev_attr_temp4_input.dev_attr.attr,
1140 &sensor_dev_attr_temp5_input.dev_attr.attr,
1141 &sensor_dev_attr_temp6_input.dev_attr.attr,
1142 &sensor_dev_attr_temp7_input.dev_attr.attr,
1143 &sensor_dev_attr_temp8_input.dev_attr.attr,
1144 &sensor_dev_attr_temp9_input.dev_attr.attr,
1145 &sensor_dev_attr_temp10_input.dev_attr.attr,
1146 &sensor_dev_attr_temp11_input.dev_attr.attr,
1147 &sensor_dev_attr_temp12_input.dev_attr.attr,
1148 &sensor_dev_attr_temp13_input.dev_attr.attr,
1149 &sensor_dev_attr_temp14_input.dev_attr.attr,
1150 &sensor_dev_attr_temp15_input.dev_attr.attr,
1151 &sensor_dev_attr_temp16_input.dev_attr.attr,
1152 &sensor_dev_attr_temp17_input.dev_attr.attr,
1153 &sensor_dev_attr_temp18_input.dev_attr.attr,
1154 &sensor_dev_attr_temp19_input.dev_attr.attr,
1155 &sensor_dev_attr_temp20_input.dev_attr.attr,
1156 &sensor_dev_attr_temp21_input.dev_attr.attr,
1157 &sensor_dev_attr_temp22_input.dev_attr.attr,
1158 &sensor_dev_attr_temp23_input.dev_attr.attr,
1159 &sensor_dev_attr_temp24_input.dev_attr.attr,
1160 &sensor_dev_attr_temp25_input.dev_attr.attr,
1161 &sensor_dev_attr_temp26_input.dev_attr.attr,
1162 &sensor_dev_attr_temp27_input.dev_attr.attr,
1163 &sensor_dev_attr_temp28_input.dev_attr.attr,
1164 &sensor_dev_attr_temp29_input.dev_attr.attr,
1165 &sensor_dev_attr_temp30_input.dev_attr.attr,
1166 &sensor_dev_attr_temp31_input.dev_attr.attr,
1167 &sensor_dev_attr_temp32_input.dev_attr.attr,
1168 &sensor_dev_attr_temp33_input.dev_attr.attr,
1169 &sensor_dev_attr_temp34_input.dev_attr.attr,
1170 &sensor_dev_attr_temp35_input.dev_attr.attr,
1174 static const struct attribute_group temperature_attributes_group =
1175 { .attrs = temperature_attributes };
1180 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1182 static int applesmc_dmi_match(const struct dmi_system_id *id)
1185 struct dmi_match_data* dmi_data = id->driver_data;
1186 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1187 applesmc_accelerometer = dmi_data->accelerometer;
1188 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1189 applesmc_accelerometer ? "with" : "without");
1190 applesmc_light = dmi_data->light;
1191 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1192 applesmc_light ? "with" : "without");
1194 applesmc_temperature_set = dmi_data->temperature_set;
1195 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1197 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1201 /* Create accelerometer ressources */
1202 static int applesmc_create_accelerometer(void)
1204 struct input_dev *idev;
1207 ret = sysfs_create_group(&pdev->dev.kobj,
1208 &accelerometer_attributes_group);
1212 applesmc_idev = input_allocate_polled_device();
1213 if (!applesmc_idev) {
1218 applesmc_idev->poll = applesmc_idev_poll;
1219 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1221 /* initial calibrate for the input device */
1222 applesmc_calibrate();
1224 /* initialize the input device */
1225 idev = applesmc_idev->input;
1226 idev->name = "applesmc";
1227 idev->id.bustype = BUS_HOST;
1228 idev->dev.parent = &pdev->dev;
1229 idev->evbit[0] = BIT_MASK(EV_ABS);
1230 input_set_abs_params(idev, ABS_X,
1231 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1232 input_set_abs_params(idev, ABS_Y,
1233 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1235 ret = input_register_polled_device(applesmc_idev);
1242 input_free_polled_device(applesmc_idev);
1245 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1248 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1252 /* Release all ressources used by the accelerometer */
1253 static void applesmc_release_accelerometer(void)
1255 input_unregister_polled_device(applesmc_idev);
1256 input_free_polled_device(applesmc_idev);
1257 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1260 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1261 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1262 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1263 /* MacBook2: accelerometer and temperature set 1 */
1264 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1265 /* MacBook: accelerometer and temperature set 2 */
1266 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1267 /* MacMini: temperature set 3 */
1268 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1269 /* MacPro: temperature set 4 */
1270 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1271 /* iMac: temperature set 5 */
1272 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1273 /* MacBook3: accelerometer and temperature set 6 */
1274 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1275 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1276 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1277 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1278 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1279 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1280 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1281 /* iMac 5: light sensor only, temperature set 10 */
1282 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1285 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1286 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1287 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1288 { applesmc_dmi_match, "Apple MacBook Air", {
1289 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1290 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1291 &applesmc_dmi_data[7]},
1292 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1293 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1294 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1295 &applesmc_dmi_data[8]},
1296 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1297 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1298 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1299 &applesmc_dmi_data[9]},
1300 { applesmc_dmi_match, "Apple MacBook Pro", {
1301 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1302 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1303 &applesmc_dmi_data[0]},
1304 { applesmc_dmi_match, "Apple MacBook (v2)", {
1305 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1306 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1307 &applesmc_dmi_data[1]},
1308 { applesmc_dmi_match, "Apple MacBook (v3)", {
1309 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1310 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1311 &applesmc_dmi_data[6]},
1312 { applesmc_dmi_match, "Apple MacBook", {
1313 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1314 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1315 &applesmc_dmi_data[2]},
1316 { applesmc_dmi_match, "Apple Macmini", {
1317 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1318 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1319 &applesmc_dmi_data[3]},
1320 { applesmc_dmi_match, "Apple MacPro2", {
1321 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1322 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1323 &applesmc_dmi_data[4]},
1324 { applesmc_dmi_match, "Apple iMac 5", {
1325 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1326 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1327 &applesmc_dmi_data[10]},
1328 { applesmc_dmi_match, "Apple iMac", {
1329 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1330 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1331 &applesmc_dmi_data[5]},
1335 static int __init applesmc_init(void)
1341 if (!dmi_check_system(applesmc_whitelist)) {
1342 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1347 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1353 ret = platform_driver_register(&applesmc_driver);
1357 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1360 ret = PTR_ERR(pdev);
1364 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1368 /* Create key enumeration sysfs files */
1369 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1373 /* create fan files */
1374 count = applesmc_get_fan_count();
1376 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1378 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1382 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1383 " but at most 4 fans are supported"
1384 " by the driver.\n");
1386 ret = sysfs_create_group(&pdev->dev.kobj,
1387 &fan_attribute_groups[3]);
1389 goto out_key_enumeration;
1391 ret = sysfs_create_group(&pdev->dev.kobj,
1392 &fan_attribute_groups[2]);
1394 goto out_key_enumeration;
1396 ret = sysfs_create_group(&pdev->dev.kobj,
1397 &fan_attribute_groups[1]);
1399 goto out_key_enumeration;
1401 ret = sysfs_create_group(&pdev->dev.kobj,
1402 &fan_attribute_groups[0]);
1411 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1413 if (temperature_attributes[i] == NULL) {
1414 printk(KERN_ERR "applesmc: More temperature sensors "
1415 "in temperature_sensors_sets (at least %i)"
1416 "than available sysfs files in "
1417 "temperature_attributes (%i), please report "
1418 "this bug.\n", i, i-1);
1419 goto out_temperature;
1421 ret = sysfs_create_file(&pdev->dev.kobj,
1422 temperature_attributes[i]);
1424 goto out_temperature;
1427 if (applesmc_accelerometer) {
1428 ret = applesmc_create_accelerometer();
1430 goto out_temperature;
1433 if (applesmc_light) {
1434 /* Add light sensor file */
1435 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1437 goto out_accelerometer;
1439 /* Create the workqueue */
1440 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1441 if (!applesmc_led_wq) {
1443 goto out_light_sysfs;
1446 /* register as a led device */
1447 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1452 hwmon_dev = hwmon_device_register(&pdev->dev);
1453 if (IS_ERR(hwmon_dev)) {
1454 ret = PTR_ERR(hwmon_dev);
1455 goto out_light_ledclass;
1458 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1464 led_classdev_unregister(&applesmc_backlight);
1467 destroy_workqueue(applesmc_led_wq);
1470 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1472 if (applesmc_accelerometer)
1473 applesmc_release_accelerometer();
1475 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1476 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1478 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1479 out_key_enumeration:
1480 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1482 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1484 platform_device_unregister(pdev);
1486 platform_driver_unregister(&applesmc_driver);
1488 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1490 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1494 static void __exit applesmc_exit(void)
1496 hwmon_device_unregister(hwmon_dev);
1497 if (applesmc_light) {
1498 led_classdev_unregister(&applesmc_backlight);
1499 destroy_workqueue(applesmc_led_wq);
1500 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1502 if (applesmc_accelerometer)
1503 applesmc_release_accelerometer();
1504 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1505 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1506 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1507 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1508 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1509 platform_device_unregister(pdev);
1510 platform_driver_unregister(&applesmc_driver);
1511 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1513 printk(KERN_INFO "applesmc: driver unloaded.\n");
1516 module_init(applesmc_init);
1517 module_exit(applesmc_exit);
1519 MODULE_AUTHOR("Nicolas Boichat");
1520 MODULE_DESCRIPTION("Apple SMC");
1521 MODULE_LICENSE("GPL v2");