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 },
121 /* Set 11: Macbook 5,1 */
122 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0P", "TN0D", "TN0P",
123 "TTF0", "Th0H", "Th1H", "ThFH", "Ts0P", "Ts0S", NULL },
124 /* Set 12: Macbook Pro 5,1 */
125 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D",
126 "TG0F", "TG0H", "TG0P", "TG0T", "TG1H", "TN0D", "TN0P", "TTF0",
127 "Th2H", "Tm0P", "Ts0P", "Ts0S", NULL },
128 /* Set 13: iMac 8,1 */
129 { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P",
130 "TL0P", "TO0P", "TW0P", "Tm0P", "Tp0P", NULL },
133 /* List of keys used to read/write fan speeds */
134 static const char* fan_speed_keys[] = {
142 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
143 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
145 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
146 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
147 #define APPLESMC_INPUT_FLAT 4
153 /* Structure to be passed to DMI_MATCH function */
154 struct dmi_match_data {
155 /* Indicates whether this computer has an accelerometer. */
157 /* Indicates whether this computer has light sensors and keyboard backlight. */
159 /* Indicates which temperature sensors set to use. */
163 static const int debug;
164 static struct platform_device *pdev;
167 static struct device *hwmon_dev;
168 static struct input_polled_dev *applesmc_idev;
170 /* Indicates whether this computer has an accelerometer. */
171 static unsigned int applesmc_accelerometer;
173 /* Indicates whether this computer has light sensors and keyboard backlight. */
174 static unsigned int applesmc_light;
176 /* Indicates which temperature sensors set to use. */
177 static unsigned int applesmc_temperature_set;
179 static DEFINE_MUTEX(applesmc_lock);
182 * Last index written to key_at_index sysfs file, and value to use for all other
183 * key_at_index_* sysfs files.
185 static unsigned int key_at_index;
187 static struct workqueue_struct *applesmc_led_wq;
190 * __wait_status - Wait up to 32ms for the status port to get a certain value
191 * (masked with 0x0f), returning zero if the value is obtained. Callers must
192 * hold applesmc_lock.
194 static int __wait_status(u8 val)
198 val = val & APPLESMC_STATUS_MASK;
200 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
202 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
205 "Waited %d us for status %x\n",
206 2 * us - APPLESMC_MIN_WAIT, val);
211 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
212 val, inb(APPLESMC_CMD_PORT));
218 * special treatment of command port - on newer macbooks, it seems necessary
219 * to resend the command byte before polling the status again. Callers must
220 * hold applesmc_lock.
222 static int send_command(u8 cmd)
225 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
226 outb(cmd, APPLESMC_CMD_PORT);
228 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
231 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
232 cmd, inb(APPLESMC_CMD_PORT));
237 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
238 * Returns zero on success or a negative error on failure. Callers must
239 * hold applesmc_lock.
241 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
245 if (len > APPLESMC_MAX_DATA_LENGTH) {
246 printk(KERN_ERR "applesmc_read_key: cannot read more than "
247 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
251 if (send_command(APPLESMC_READ_CMD))
254 for (i = 0; i < 4; i++) {
255 outb(key[i], APPLESMC_DATA_PORT);
256 if (__wait_status(0x04))
260 printk(KERN_DEBUG "<%s", key);
262 outb(len, APPLESMC_DATA_PORT);
264 printk(KERN_DEBUG ">%x", len);
266 for (i = 0; i < len; i++) {
267 if (__wait_status(0x05))
269 buffer[i] = inb(APPLESMC_DATA_PORT);
271 printk(KERN_DEBUG "<%x", buffer[i]);
274 printk(KERN_DEBUG "\n");
280 * applesmc_write_key - writes len bytes from buffer to a given key.
281 * Returns zero on success or a negative error on failure. Callers must
282 * hold applesmc_lock.
284 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
288 if (len > APPLESMC_MAX_DATA_LENGTH) {
289 printk(KERN_ERR "applesmc_write_key: cannot write more than "
290 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
294 if (send_command(APPLESMC_WRITE_CMD))
297 for (i = 0; i < 4; i++) {
298 outb(key[i], APPLESMC_DATA_PORT);
299 if (__wait_status(0x04))
303 outb(len, APPLESMC_DATA_PORT);
305 for (i = 0; i < len; i++) {
306 if (__wait_status(0x04))
308 outb(buffer[i], APPLESMC_DATA_PORT);
315 * applesmc_get_key_at_index - get key at index, and put the result in key
316 * (char[6]). Returns zero on success or a negative error on failure. Callers
317 * must hold applesmc_lock.
319 static int applesmc_get_key_at_index(int index, char* key)
323 readkey[0] = index >> 24;
324 readkey[1] = index >> 16;
325 readkey[2] = index >> 8;
328 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
331 for (i = 0; i < 4; i++) {
332 outb(readkey[i], APPLESMC_DATA_PORT);
333 if (__wait_status(0x04))
337 outb(4, APPLESMC_DATA_PORT);
339 for (i = 0; i < 4; i++) {
340 if (__wait_status(0x05))
342 key[i] = inb(APPLESMC_DATA_PORT);
350 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
351 * Returns zero on success or a negative error on failure. Callers must
352 * hold applesmc_lock.
354 static int applesmc_get_key_type(char* key, char* type)
358 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
361 for (i = 0; i < 4; i++) {
362 outb(key[i], APPLESMC_DATA_PORT);
363 if (__wait_status(0x04))
367 outb(6, APPLESMC_DATA_PORT);
369 for (i = 0; i < 6; i++) {
370 if (__wait_status(0x05))
372 type[i] = inb(APPLESMC_DATA_PORT);
380 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
381 * hold applesmc_lock.
383 static int applesmc_read_motion_sensor(int index, s16* value)
390 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
393 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
396 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
402 *value = ((s16)buffer[0] << 8) | buffer[1];
408 * applesmc_device_init - initialize the accelerometer. Returns zero on success
409 * and negative error code on failure. Can sleep.
411 static int applesmc_device_init(void)
413 int total, ret = -ENXIO;
416 if (!applesmc_accelerometer)
419 mutex_lock(&applesmc_lock);
421 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
423 printk(KERN_DEBUG "applesmc try %d\n", total);
424 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
425 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
426 if (total == INIT_TIMEOUT_MSECS) {
427 printk(KERN_DEBUG "applesmc: device has"
428 " already been initialized"
429 " (0x%02x, 0x%02x).\n",
430 buffer[0], buffer[1]);
432 printk(KERN_DEBUG "applesmc: device"
433 " successfully initialized"
434 " (0x%02x, 0x%02x).\n",
435 buffer[0], buffer[1]);
442 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
443 msleep(INIT_WAIT_MSECS);
446 printk(KERN_WARNING "applesmc: failed to init the device\n");
449 mutex_unlock(&applesmc_lock);
454 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
457 static int applesmc_get_fan_count(void)
462 mutex_lock(&applesmc_lock);
464 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
466 mutex_unlock(&applesmc_lock);
473 /* Device model stuff */
474 static int applesmc_probe(struct platform_device *dev)
478 ret = applesmc_device_init();
482 printk(KERN_INFO "applesmc: device successfully initialized.\n");
486 static int applesmc_resume(struct platform_device *dev)
488 return applesmc_device_init();
491 static struct platform_driver applesmc_driver = {
492 .probe = applesmc_probe,
493 .resume = applesmc_resume,
496 .owner = THIS_MODULE,
501 * applesmc_calibrate - Set our "resting" values. Callers must
502 * hold applesmc_lock.
504 static void applesmc_calibrate(void)
506 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
507 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
511 static void applesmc_idev_poll(struct input_polled_dev *dev)
513 struct input_dev *idev = dev->input;
516 mutex_lock(&applesmc_lock);
518 if (applesmc_read_motion_sensor(SENSOR_X, &x))
520 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
524 input_report_abs(idev, ABS_X, x - rest_x);
525 input_report_abs(idev, ABS_Y, y - rest_y);
529 mutex_unlock(&applesmc_lock);
534 static ssize_t applesmc_name_show(struct device *dev,
535 struct device_attribute *attr, char *buf)
537 return snprintf(buf, PAGE_SIZE, "applesmc\n");
540 static ssize_t applesmc_position_show(struct device *dev,
541 struct device_attribute *attr, char *buf)
546 mutex_lock(&applesmc_lock);
548 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
551 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
554 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
559 mutex_unlock(&applesmc_lock);
563 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
566 static ssize_t applesmc_light_show(struct device *dev,
567 struct device_attribute *attr, char *sysfsbuf)
569 static int data_length;
571 u8 left = 0, right = 0;
572 u8 buffer[10], query[6];
574 mutex_lock(&applesmc_lock);
577 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
580 data_length = clamp_val(query[0], 0, 10);
581 printk(KERN_INFO "applesmc: light sensor data length set to "
582 "%d\n", data_length);
585 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
589 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
593 mutex_unlock(&applesmc_lock);
597 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
600 /* Displays degree Celsius * 1000 */
601 static ssize_t applesmc_show_temperature(struct device *dev,
602 struct device_attribute *devattr, char *sysfsbuf)
607 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
609 temperature_sensors_sets[applesmc_temperature_set][attr->index];
611 mutex_lock(&applesmc_lock);
613 ret = applesmc_read_key(key, buffer, 2);
614 temp = buffer[0]*1000;
615 temp += (buffer[1] >> 6) * 250;
617 mutex_unlock(&applesmc_lock);
622 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
625 static ssize_t applesmc_show_fan_speed(struct device *dev,
626 struct device_attribute *attr, char *sysfsbuf)
629 unsigned int speed = 0;
632 struct sensor_device_attribute_2 *sensor_attr =
633 to_sensor_dev_attr_2(attr);
635 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
636 newkey[1] = '0' + sensor_attr->index;
637 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
638 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
641 mutex_lock(&applesmc_lock);
643 ret = applesmc_read_key(newkey, buffer, 2);
644 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
646 mutex_unlock(&applesmc_lock);
650 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
653 static ssize_t applesmc_store_fan_speed(struct device *dev,
654 struct device_attribute *attr,
655 const char *sysfsbuf, size_t count)
661 struct sensor_device_attribute_2 *sensor_attr =
662 to_sensor_dev_attr_2(attr);
664 speed = simple_strtoul(sysfsbuf, NULL, 10);
666 if (speed > 0x4000) /* Bigger than a 14-bit value */
669 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
670 newkey[1] = '0' + sensor_attr->index;
671 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
672 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
675 mutex_lock(&applesmc_lock);
677 buffer[0] = (speed >> 6) & 0xff;
678 buffer[1] = (speed << 2) & 0xff;
679 ret = applesmc_write_key(newkey, buffer, 2);
681 mutex_unlock(&applesmc_lock);
688 static ssize_t applesmc_show_fan_manual(struct device *dev,
689 struct device_attribute *devattr, char *sysfsbuf)
694 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
696 mutex_lock(&applesmc_lock);
698 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
699 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
701 mutex_unlock(&applesmc_lock);
705 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
708 static ssize_t applesmc_store_fan_manual(struct device *dev,
709 struct device_attribute *devattr,
710 const char *sysfsbuf, size_t count)
716 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
718 input = simple_strtoul(sysfsbuf, NULL, 10);
720 mutex_lock(&applesmc_lock);
722 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
723 val = (buffer[0] << 8 | buffer[1]);
728 val = val | (0x01 << attr->index);
730 val = val & ~(0x01 << attr->index);
732 buffer[0] = (val >> 8) & 0xFF;
733 buffer[1] = val & 0xFF;
735 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
738 mutex_unlock(&applesmc_lock);
745 static ssize_t applesmc_show_fan_position(struct device *dev,
746 struct device_attribute *attr, char *sysfsbuf)
751 struct sensor_device_attribute_2 *sensor_attr =
752 to_sensor_dev_attr_2(attr);
754 newkey[0] = FAN_POSITION[0];
755 newkey[1] = '0' + sensor_attr->index;
756 newkey[2] = FAN_POSITION[2];
757 newkey[3] = FAN_POSITION[3];
760 mutex_lock(&applesmc_lock);
762 ret = applesmc_read_key(newkey, buffer, 16);
765 mutex_unlock(&applesmc_lock);
769 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
772 static ssize_t applesmc_calibrate_show(struct device *dev,
773 struct device_attribute *attr, char *sysfsbuf)
775 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
778 static ssize_t applesmc_calibrate_store(struct device *dev,
779 struct device_attribute *attr, const char *sysfsbuf, size_t count)
781 mutex_lock(&applesmc_lock);
782 applesmc_calibrate();
783 mutex_unlock(&applesmc_lock);
788 /* Store the next backlight value to be written by the work */
789 static unsigned int backlight_value;
791 static void applesmc_backlight_set(struct work_struct *work)
795 mutex_lock(&applesmc_lock);
796 buffer[0] = backlight_value;
798 applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
799 mutex_unlock(&applesmc_lock);
801 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
803 static void applesmc_brightness_set(struct led_classdev *led_cdev,
804 enum led_brightness value)
808 backlight_value = value;
809 ret = queue_work(applesmc_led_wq, &backlight_work);
812 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
815 static ssize_t applesmc_key_count_show(struct device *dev,
816 struct device_attribute *attr, char *sysfsbuf)
822 mutex_lock(&applesmc_lock);
824 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
825 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
826 ((u32)buffer[2]<<8) + buffer[3];
828 mutex_unlock(&applesmc_lock);
832 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
835 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
836 struct device_attribute *attr, char *sysfsbuf)
842 mutex_lock(&applesmc_lock);
844 ret = applesmc_get_key_at_index(key_at_index, key);
846 if (ret || !key[0]) {
847 mutex_unlock(&applesmc_lock);
852 ret = applesmc_get_key_type(key, info);
855 mutex_unlock(&applesmc_lock);
861 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
862 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
864 ret = applesmc_read_key(key, sysfsbuf, info[0]);
866 mutex_unlock(&applesmc_lock);
875 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
876 struct device_attribute *attr, char *sysfsbuf)
882 mutex_lock(&applesmc_lock);
884 ret = applesmc_get_key_at_index(key_at_index, key);
886 if (ret || !key[0]) {
887 mutex_unlock(&applesmc_lock);
892 ret = applesmc_get_key_type(key, info);
894 mutex_unlock(&applesmc_lock);
897 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
902 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
903 struct device_attribute *attr, char *sysfsbuf)
909 mutex_lock(&applesmc_lock);
911 ret = applesmc_get_key_at_index(key_at_index, key);
913 if (ret || !key[0]) {
914 mutex_unlock(&applesmc_lock);
919 ret = applesmc_get_key_type(key, info);
921 mutex_unlock(&applesmc_lock);
924 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
929 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
930 struct device_attribute *attr, char *sysfsbuf)
935 mutex_lock(&applesmc_lock);
937 ret = applesmc_get_key_at_index(key_at_index, key);
939 mutex_unlock(&applesmc_lock);
942 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
947 static ssize_t applesmc_key_at_index_show(struct device *dev,
948 struct device_attribute *attr, char *sysfsbuf)
950 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
953 static ssize_t applesmc_key_at_index_store(struct device *dev,
954 struct device_attribute *attr, const char *sysfsbuf, size_t count)
956 mutex_lock(&applesmc_lock);
958 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
960 mutex_unlock(&applesmc_lock);
965 static struct led_classdev applesmc_backlight = {
966 .name = "smc::kbd_backlight",
967 .default_trigger = "nand-disk",
968 .brightness_set = applesmc_brightness_set,
971 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
973 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
974 static DEVICE_ATTR(calibrate, 0644,
975 applesmc_calibrate_show, applesmc_calibrate_store);
977 static struct attribute *accelerometer_attributes[] = {
978 &dev_attr_position.attr,
979 &dev_attr_calibrate.attr,
983 static const struct attribute_group accelerometer_attributes_group =
984 { .attrs = accelerometer_attributes };
986 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
988 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
989 static DEVICE_ATTR(key_at_index, 0644,
990 applesmc_key_at_index_show, applesmc_key_at_index_store);
991 static DEVICE_ATTR(key_at_index_name, 0444,
992 applesmc_key_at_index_name_show, NULL);
993 static DEVICE_ATTR(key_at_index_type, 0444,
994 applesmc_key_at_index_type_show, NULL);
995 static DEVICE_ATTR(key_at_index_data_length, 0444,
996 applesmc_key_at_index_data_length_show, NULL);
997 static DEVICE_ATTR(key_at_index_data, 0444,
998 applesmc_key_at_index_read_show, NULL);
1000 static struct attribute *key_enumeration_attributes[] = {
1001 &dev_attr_key_count.attr,
1002 &dev_attr_key_at_index.attr,
1003 &dev_attr_key_at_index_name.attr,
1004 &dev_attr_key_at_index_type.attr,
1005 &dev_attr_key_at_index_data_length.attr,
1006 &dev_attr_key_at_index_data.attr,
1010 static const struct attribute_group key_enumeration_group =
1011 { .attrs = key_enumeration_attributes };
1014 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1015 * - show actual speed
1016 * - show/store minimum speed
1017 * - show maximum speed
1019 * - show/store target speed
1020 * - show/store manual mode
1022 #define sysfs_fan_speeds_offset(offset) \
1023 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1024 applesmc_show_fan_speed, NULL, 0, offset-1); \
1026 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1027 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1029 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1030 applesmc_show_fan_speed, NULL, 2, offset-1); \
1032 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1033 applesmc_show_fan_speed, NULL, 3, offset-1); \
1035 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1036 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1038 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1039 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1041 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1042 applesmc_show_fan_position, NULL, offset-1); \
1044 static struct attribute *fan##offset##_attributes[] = { \
1045 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1046 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1047 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1048 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1049 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1050 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1051 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1056 * Create the needed functions for each fan using the macro defined above
1057 * (4 fans are supported)
1059 sysfs_fan_speeds_offset(1);
1060 sysfs_fan_speeds_offset(2);
1061 sysfs_fan_speeds_offset(3);
1062 sysfs_fan_speeds_offset(4);
1064 static const struct attribute_group fan_attribute_groups[] = {
1065 { .attrs = fan1_attributes },
1066 { .attrs = fan2_attributes },
1067 { .attrs = fan3_attributes },
1068 { .attrs = fan4_attributes },
1072 * Temperature sensors sysfs entries.
1074 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1075 applesmc_show_temperature, NULL, 0);
1076 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1077 applesmc_show_temperature, NULL, 1);
1078 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1079 applesmc_show_temperature, NULL, 2);
1080 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1081 applesmc_show_temperature, NULL, 3);
1082 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1083 applesmc_show_temperature, NULL, 4);
1084 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1085 applesmc_show_temperature, NULL, 5);
1086 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1087 applesmc_show_temperature, NULL, 6);
1088 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1089 applesmc_show_temperature, NULL, 7);
1090 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1091 applesmc_show_temperature, NULL, 8);
1092 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1093 applesmc_show_temperature, NULL, 9);
1094 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1095 applesmc_show_temperature, NULL, 10);
1096 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1097 applesmc_show_temperature, NULL, 11);
1098 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1099 applesmc_show_temperature, NULL, 12);
1100 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1101 applesmc_show_temperature, NULL, 13);
1102 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1103 applesmc_show_temperature, NULL, 14);
1104 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1105 applesmc_show_temperature, NULL, 15);
1106 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1107 applesmc_show_temperature, NULL, 16);
1108 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1109 applesmc_show_temperature, NULL, 17);
1110 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1111 applesmc_show_temperature, NULL, 18);
1112 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1113 applesmc_show_temperature, NULL, 19);
1114 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1115 applesmc_show_temperature, NULL, 20);
1116 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1117 applesmc_show_temperature, NULL, 21);
1118 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1119 applesmc_show_temperature, NULL, 22);
1120 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1121 applesmc_show_temperature, NULL, 23);
1122 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1123 applesmc_show_temperature, NULL, 24);
1124 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1125 applesmc_show_temperature, NULL, 25);
1126 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1127 applesmc_show_temperature, NULL, 26);
1128 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1129 applesmc_show_temperature, NULL, 27);
1130 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1131 applesmc_show_temperature, NULL, 28);
1132 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1133 applesmc_show_temperature, NULL, 29);
1134 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1135 applesmc_show_temperature, NULL, 30);
1136 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1137 applesmc_show_temperature, NULL, 31);
1138 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1139 applesmc_show_temperature, NULL, 32);
1140 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1141 applesmc_show_temperature, NULL, 33);
1142 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1143 applesmc_show_temperature, NULL, 34);
1145 static struct attribute *temperature_attributes[] = {
1146 &sensor_dev_attr_temp1_input.dev_attr.attr,
1147 &sensor_dev_attr_temp2_input.dev_attr.attr,
1148 &sensor_dev_attr_temp3_input.dev_attr.attr,
1149 &sensor_dev_attr_temp4_input.dev_attr.attr,
1150 &sensor_dev_attr_temp5_input.dev_attr.attr,
1151 &sensor_dev_attr_temp6_input.dev_attr.attr,
1152 &sensor_dev_attr_temp7_input.dev_attr.attr,
1153 &sensor_dev_attr_temp8_input.dev_attr.attr,
1154 &sensor_dev_attr_temp9_input.dev_attr.attr,
1155 &sensor_dev_attr_temp10_input.dev_attr.attr,
1156 &sensor_dev_attr_temp11_input.dev_attr.attr,
1157 &sensor_dev_attr_temp12_input.dev_attr.attr,
1158 &sensor_dev_attr_temp13_input.dev_attr.attr,
1159 &sensor_dev_attr_temp14_input.dev_attr.attr,
1160 &sensor_dev_attr_temp15_input.dev_attr.attr,
1161 &sensor_dev_attr_temp16_input.dev_attr.attr,
1162 &sensor_dev_attr_temp17_input.dev_attr.attr,
1163 &sensor_dev_attr_temp18_input.dev_attr.attr,
1164 &sensor_dev_attr_temp19_input.dev_attr.attr,
1165 &sensor_dev_attr_temp20_input.dev_attr.attr,
1166 &sensor_dev_attr_temp21_input.dev_attr.attr,
1167 &sensor_dev_attr_temp22_input.dev_attr.attr,
1168 &sensor_dev_attr_temp23_input.dev_attr.attr,
1169 &sensor_dev_attr_temp24_input.dev_attr.attr,
1170 &sensor_dev_attr_temp25_input.dev_attr.attr,
1171 &sensor_dev_attr_temp26_input.dev_attr.attr,
1172 &sensor_dev_attr_temp27_input.dev_attr.attr,
1173 &sensor_dev_attr_temp28_input.dev_attr.attr,
1174 &sensor_dev_attr_temp29_input.dev_attr.attr,
1175 &sensor_dev_attr_temp30_input.dev_attr.attr,
1176 &sensor_dev_attr_temp31_input.dev_attr.attr,
1177 &sensor_dev_attr_temp32_input.dev_attr.attr,
1178 &sensor_dev_attr_temp33_input.dev_attr.attr,
1179 &sensor_dev_attr_temp34_input.dev_attr.attr,
1180 &sensor_dev_attr_temp35_input.dev_attr.attr,
1184 static const struct attribute_group temperature_attributes_group =
1185 { .attrs = temperature_attributes };
1190 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1192 static int applesmc_dmi_match(const struct dmi_system_id *id)
1195 struct dmi_match_data* dmi_data = id->driver_data;
1196 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1197 applesmc_accelerometer = dmi_data->accelerometer;
1198 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1199 applesmc_accelerometer ? "with" : "without");
1200 applesmc_light = dmi_data->light;
1201 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1202 applesmc_light ? "with" : "without");
1204 applesmc_temperature_set = dmi_data->temperature_set;
1205 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1207 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1211 /* Create accelerometer ressources */
1212 static int applesmc_create_accelerometer(void)
1214 struct input_dev *idev;
1217 ret = sysfs_create_group(&pdev->dev.kobj,
1218 &accelerometer_attributes_group);
1222 applesmc_idev = input_allocate_polled_device();
1223 if (!applesmc_idev) {
1228 applesmc_idev->poll = applesmc_idev_poll;
1229 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1231 /* initial calibrate for the input device */
1232 applesmc_calibrate();
1234 /* initialize the input device */
1235 idev = applesmc_idev->input;
1236 idev->name = "applesmc";
1237 idev->id.bustype = BUS_HOST;
1238 idev->dev.parent = &pdev->dev;
1239 idev->evbit[0] = BIT_MASK(EV_ABS);
1240 input_set_abs_params(idev, ABS_X,
1241 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1242 input_set_abs_params(idev, ABS_Y,
1243 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1245 ret = input_register_polled_device(applesmc_idev);
1252 input_free_polled_device(applesmc_idev);
1255 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1258 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1262 /* Release all ressources used by the accelerometer */
1263 static void applesmc_release_accelerometer(void)
1265 input_unregister_polled_device(applesmc_idev);
1266 input_free_polled_device(applesmc_idev);
1267 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1270 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1271 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1272 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1273 /* MacBook2: accelerometer and temperature set 1 */
1274 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1275 /* MacBook: accelerometer and temperature set 2 */
1276 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1277 /* MacMini: temperature set 3 */
1278 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1279 /* MacPro: temperature set 4 */
1280 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1281 /* iMac: temperature set 5 */
1282 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1283 /* MacBook3: accelerometer and temperature set 6 */
1284 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1285 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1286 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1287 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1288 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1289 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1290 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1291 /* iMac 5: light sensor only, temperature set 10 */
1292 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1293 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1294 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
1295 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1296 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
1297 /* iMac 8: light sensor only, temperature set 13 */
1298 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
1301 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1302 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1303 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1304 { applesmc_dmi_match, "Apple MacBook Air", {
1305 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1306 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1307 &applesmc_dmi_data[7]},
1308 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1309 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1310 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1311 &applesmc_dmi_data[12]},
1312 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1313 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1314 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1315 &applesmc_dmi_data[8]},
1316 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1317 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1318 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1319 &applesmc_dmi_data[9]},
1320 { applesmc_dmi_match, "Apple MacBook Pro", {
1321 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1322 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1323 &applesmc_dmi_data[0]},
1324 { applesmc_dmi_match, "Apple MacBook (v2)", {
1325 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1326 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1327 &applesmc_dmi_data[1]},
1328 { applesmc_dmi_match, "Apple MacBook (v3)", {
1329 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1330 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1331 &applesmc_dmi_data[6]},
1332 { applesmc_dmi_match, "Apple MacBook 5", {
1333 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1334 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1335 &applesmc_dmi_data[11]},
1336 { applesmc_dmi_match, "Apple MacBook", {
1337 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1338 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1339 &applesmc_dmi_data[2]},
1340 { applesmc_dmi_match, "Apple Macmini", {
1341 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1342 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1343 &applesmc_dmi_data[3]},
1344 { applesmc_dmi_match, "Apple MacPro2", {
1345 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1346 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1347 &applesmc_dmi_data[4]},
1348 { applesmc_dmi_match, "Apple iMac 8", {
1349 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1350 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1351 &applesmc_dmi_data[13]},
1352 { applesmc_dmi_match, "Apple iMac 5", {
1353 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1354 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1355 &applesmc_dmi_data[10]},
1356 { applesmc_dmi_match, "Apple iMac", {
1357 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1358 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1359 &applesmc_dmi_data[5]},
1363 static int __init applesmc_init(void)
1369 if (!dmi_check_system(applesmc_whitelist)) {
1370 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1375 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1381 ret = platform_driver_register(&applesmc_driver);
1385 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1388 ret = PTR_ERR(pdev);
1392 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1396 /* Create key enumeration sysfs files */
1397 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1401 /* create fan files */
1402 count = applesmc_get_fan_count();
1404 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1406 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1410 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1411 " but at most 4 fans are supported"
1412 " by the driver.\n");
1414 ret = sysfs_create_group(&pdev->dev.kobj,
1415 &fan_attribute_groups[3]);
1417 goto out_key_enumeration;
1419 ret = sysfs_create_group(&pdev->dev.kobj,
1420 &fan_attribute_groups[2]);
1422 goto out_key_enumeration;
1424 ret = sysfs_create_group(&pdev->dev.kobj,
1425 &fan_attribute_groups[1]);
1427 goto out_key_enumeration;
1429 ret = sysfs_create_group(&pdev->dev.kobj,
1430 &fan_attribute_groups[0]);
1439 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1441 if (temperature_attributes[i] == NULL) {
1442 printk(KERN_ERR "applesmc: More temperature sensors "
1443 "in temperature_sensors_sets (at least %i)"
1444 "than available sysfs files in "
1445 "temperature_attributes (%i), please report "
1446 "this bug.\n", i, i-1);
1447 goto out_temperature;
1449 ret = sysfs_create_file(&pdev->dev.kobj,
1450 temperature_attributes[i]);
1452 goto out_temperature;
1455 if (applesmc_accelerometer) {
1456 ret = applesmc_create_accelerometer();
1458 goto out_temperature;
1461 if (applesmc_light) {
1462 /* Add light sensor file */
1463 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1465 goto out_accelerometer;
1467 /* Create the workqueue */
1468 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1469 if (!applesmc_led_wq) {
1471 goto out_light_sysfs;
1474 /* register as a led device */
1475 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1480 hwmon_dev = hwmon_device_register(&pdev->dev);
1481 if (IS_ERR(hwmon_dev)) {
1482 ret = PTR_ERR(hwmon_dev);
1483 goto out_light_ledclass;
1486 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1492 led_classdev_unregister(&applesmc_backlight);
1495 destroy_workqueue(applesmc_led_wq);
1498 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1500 if (applesmc_accelerometer)
1501 applesmc_release_accelerometer();
1503 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1504 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1506 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1507 out_key_enumeration:
1508 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1510 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1512 platform_device_unregister(pdev);
1514 platform_driver_unregister(&applesmc_driver);
1516 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1518 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1522 static void __exit applesmc_exit(void)
1524 hwmon_device_unregister(hwmon_dev);
1525 if (applesmc_light) {
1526 led_classdev_unregister(&applesmc_backlight);
1527 destroy_workqueue(applesmc_led_wq);
1528 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1530 if (applesmc_accelerometer)
1531 applesmc_release_accelerometer();
1532 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1533 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1534 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1535 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1536 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1537 platform_device_unregister(pdev);
1538 platform_driver_unregister(&applesmc_driver);
1539 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1541 printk(KERN_INFO "applesmc: driver unloaded.\n");
1544 module_init(applesmc_init);
1545 module_exit(applesmc_exit);
1547 MODULE_AUTHOR("Nicolas Boichat");
1548 MODULE_DESCRIPTION("Apple SMC");
1549 MODULE_LICENSE("GPL v2");