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[][41] = {
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 },
131 /* Set 14: iMac 6,1 */
132 { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P",
133 "TO0P", "Tp0P", NULL },
134 /* Set 15: MacBook Air 2,1 */
135 { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TN0D", "TTF0",
136 "TV0P", "TVFP", "TW0P", "Th0P", "Tp0P", "Tp1P", "TpFP", "Ts0P",
138 /* Set 16: Mac Pro 3,1 (2 x Quad-Core) */
139 { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
140 "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "TH0P", "TH1P",
141 "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", "TM1P",
142 "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S",
143 "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S",
145 /* Set 17: iMac 9,1 */
146 { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P",
147 "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL },
148 /* Set 18: MacBook Pro 2,2 */
149 { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0",
150 "Th0H", "Th1H", "Tm0P", "Ts0P", NULL },
151 /* Set 19: Macbook Pro 5,3 */
152 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D",
153 "TG0F", "TG0H", "TG0P", "TG0T", "TN0D", "TN0P", "TTF0", "Th2H",
154 "Tm0P", "Ts0P", "Ts0S", NULL },
155 /* Set 20: MacBook Pro 5,4 */
156 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TN0D",
157 "TN0P", "TTF0", "Th2H", "Ts0P", "Ts0S", NULL },
158 /* Set 21: MacBook Pro 6,2 */
159 { "TB0T", "TB1T", "TB2T", "TC0C", "TC0D", "TC0P", "TC1C", "TG0D",
160 "TG0P", "TG0T", "TMCD", "TP0P", "TPCD", "Th1H", "Th2H", "Tm0P",
161 "Ts0P", "Ts0S", NULL },
164 /* List of keys used to read/write fan speeds */
165 static const char* fan_speed_keys[] = {
173 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
174 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
176 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
177 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
178 #define APPLESMC_INPUT_FLAT 4
184 /* Structure to be passed to DMI_MATCH function */
185 struct dmi_match_data {
186 /* Indicates whether this computer has an accelerometer. */
188 /* Indicates whether this computer has light sensors and keyboard backlight. */
190 /* Indicates which temperature sensors set to use. */
194 static const int debug;
195 static struct platform_device *pdev;
198 static u8 backlight_state[2];
200 static struct device *hwmon_dev;
201 static struct input_polled_dev *applesmc_idev;
203 /* Indicates whether this computer has an accelerometer. */
204 static unsigned int applesmc_accelerometer;
206 /* Indicates whether this computer has light sensors and keyboard backlight. */
207 static unsigned int applesmc_light;
209 /* The number of fans handled by the driver */
210 static unsigned int fans_handled;
212 /* Indicates which temperature sensors set to use. */
213 static unsigned int applesmc_temperature_set;
215 static DEFINE_MUTEX(applesmc_lock);
218 * Last index written to key_at_index sysfs file, and value to use for all other
219 * key_at_index_* sysfs files.
221 static unsigned int key_at_index;
223 static struct workqueue_struct *applesmc_led_wq;
226 * __wait_status - Wait up to 32ms for the status port to get a certain value
227 * (masked with 0x0f), returning zero if the value is obtained. Callers must
228 * hold applesmc_lock.
230 static int __wait_status(u8 val)
234 val = val & APPLESMC_STATUS_MASK;
236 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
238 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
241 "Waited %d us for status %x\n",
242 2 * us - APPLESMC_MIN_WAIT, val);
247 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
248 val, inb(APPLESMC_CMD_PORT));
254 * special treatment of command port - on newer macbooks, it seems necessary
255 * to resend the command byte before polling the status again. Callers must
256 * hold applesmc_lock.
258 static int send_command(u8 cmd)
261 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
262 outb(cmd, APPLESMC_CMD_PORT);
264 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
267 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
268 cmd, inb(APPLESMC_CMD_PORT));
273 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
274 * Returns zero on success or a negative error on failure. Callers must
275 * hold applesmc_lock.
277 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
281 if (len > APPLESMC_MAX_DATA_LENGTH) {
282 printk(KERN_ERR "applesmc_read_key: cannot read more than "
283 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
287 if (send_command(APPLESMC_READ_CMD))
290 for (i = 0; i < 4; i++) {
291 outb(key[i], APPLESMC_DATA_PORT);
292 if (__wait_status(0x04))
296 printk(KERN_DEBUG "<%s", key);
298 outb(len, APPLESMC_DATA_PORT);
300 printk(KERN_DEBUG ">%x", len);
302 for (i = 0; i < len; i++) {
303 if (__wait_status(0x05))
305 buffer[i] = inb(APPLESMC_DATA_PORT);
307 printk(KERN_DEBUG "<%x", buffer[i]);
310 printk(KERN_DEBUG "\n");
316 * applesmc_write_key - writes len bytes from buffer to a given key.
317 * Returns zero on success or a negative error on failure. Callers must
318 * hold applesmc_lock.
320 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
324 if (len > APPLESMC_MAX_DATA_LENGTH) {
325 printk(KERN_ERR "applesmc_write_key: cannot write more than "
326 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
330 if (send_command(APPLESMC_WRITE_CMD))
333 for (i = 0; i < 4; i++) {
334 outb(key[i], APPLESMC_DATA_PORT);
335 if (__wait_status(0x04))
339 outb(len, APPLESMC_DATA_PORT);
341 for (i = 0; i < len; i++) {
342 if (__wait_status(0x04))
344 outb(buffer[i], APPLESMC_DATA_PORT);
351 * applesmc_get_key_at_index - get key at index, and put the result in key
352 * (char[6]). Returns zero on success or a negative error on failure. Callers
353 * must hold applesmc_lock.
355 static int applesmc_get_key_at_index(int index, char* key)
359 readkey[0] = index >> 24;
360 readkey[1] = index >> 16;
361 readkey[2] = index >> 8;
364 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
367 for (i = 0; i < 4; i++) {
368 outb(readkey[i], APPLESMC_DATA_PORT);
369 if (__wait_status(0x04))
373 outb(4, APPLESMC_DATA_PORT);
375 for (i = 0; i < 4; i++) {
376 if (__wait_status(0x05))
378 key[i] = inb(APPLESMC_DATA_PORT);
386 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
387 * Returns zero on success or a negative error on failure. Callers must
388 * hold applesmc_lock.
390 static int applesmc_get_key_type(char* key, char* type)
394 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
397 for (i = 0; i < 4; i++) {
398 outb(key[i], APPLESMC_DATA_PORT);
399 if (__wait_status(0x04))
403 outb(6, APPLESMC_DATA_PORT);
405 for (i = 0; i < 6; i++) {
406 if (__wait_status(0x05))
408 type[i] = inb(APPLESMC_DATA_PORT);
416 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
417 * hold applesmc_lock.
419 static int applesmc_read_motion_sensor(int index, s16* value)
426 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
429 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
432 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
438 *value = ((s16)buffer[0] << 8) | buffer[1];
444 * applesmc_device_init - initialize the accelerometer. Returns zero on success
445 * and negative error code on failure. Can sleep.
447 static int applesmc_device_init(void)
449 int total, ret = -ENXIO;
452 if (!applesmc_accelerometer)
455 mutex_lock(&applesmc_lock);
457 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
459 printk(KERN_DEBUG "applesmc try %d\n", total);
460 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
461 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
462 if (total == INIT_TIMEOUT_MSECS) {
463 printk(KERN_DEBUG "applesmc: device has"
464 " already been initialized"
465 " (0x%02x, 0x%02x).\n",
466 buffer[0], buffer[1]);
468 printk(KERN_DEBUG "applesmc: device"
469 " successfully initialized"
470 " (0x%02x, 0x%02x).\n",
471 buffer[0], buffer[1]);
478 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
479 msleep(INIT_WAIT_MSECS);
482 printk(KERN_WARNING "applesmc: failed to init the device\n");
485 mutex_unlock(&applesmc_lock);
490 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
493 static int applesmc_get_fan_count(void)
498 mutex_lock(&applesmc_lock);
500 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
502 mutex_unlock(&applesmc_lock);
509 /* Device model stuff */
510 static int applesmc_probe(struct platform_device *dev)
514 ret = applesmc_device_init();
518 printk(KERN_INFO "applesmc: device successfully initialized.\n");
522 /* Synchronize device with memorized backlight state */
523 static int applesmc_pm_resume(struct device *dev)
525 mutex_lock(&applesmc_lock);
527 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
528 mutex_unlock(&applesmc_lock);
532 /* Reinitialize device on resume from hibernation */
533 static int applesmc_pm_restore(struct device *dev)
535 int ret = applesmc_device_init();
538 return applesmc_pm_resume(dev);
541 static const struct dev_pm_ops applesmc_pm_ops = {
542 .resume = applesmc_pm_resume,
543 .restore = applesmc_pm_restore,
546 static struct platform_driver applesmc_driver = {
547 .probe = applesmc_probe,
550 .owner = THIS_MODULE,
551 .pm = &applesmc_pm_ops,
556 * applesmc_calibrate - Set our "resting" values. Callers must
557 * hold applesmc_lock.
559 static void applesmc_calibrate(void)
561 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
562 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
566 static void applesmc_idev_poll(struct input_polled_dev *dev)
568 struct input_dev *idev = dev->input;
571 mutex_lock(&applesmc_lock);
573 if (applesmc_read_motion_sensor(SENSOR_X, &x))
575 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
579 input_report_abs(idev, ABS_X, x - rest_x);
580 input_report_abs(idev, ABS_Y, y - rest_y);
584 mutex_unlock(&applesmc_lock);
589 static ssize_t applesmc_name_show(struct device *dev,
590 struct device_attribute *attr, char *buf)
592 return snprintf(buf, PAGE_SIZE, "applesmc\n");
595 static ssize_t applesmc_position_show(struct device *dev,
596 struct device_attribute *attr, char *buf)
601 mutex_lock(&applesmc_lock);
603 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
606 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
609 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
614 mutex_unlock(&applesmc_lock);
618 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
621 static ssize_t applesmc_light_show(struct device *dev,
622 struct device_attribute *attr, char *sysfsbuf)
624 static int data_length;
626 u8 left = 0, right = 0;
627 u8 buffer[10], query[6];
629 mutex_lock(&applesmc_lock);
632 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
635 data_length = clamp_val(query[0], 0, 10);
636 printk(KERN_INFO "applesmc: light sensor data length set to "
637 "%d\n", data_length);
640 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
641 /* newer macbooks report a single 10-bit bigendian value */
642 if (data_length == 10) {
643 left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2;
649 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
653 mutex_unlock(&applesmc_lock);
657 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
660 /* Displays degree Celsius * 1000 */
661 static ssize_t applesmc_show_temperature(struct device *dev,
662 struct device_attribute *devattr, char *sysfsbuf)
667 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
669 temperature_sensors_sets[applesmc_temperature_set][attr->index];
671 mutex_lock(&applesmc_lock);
673 ret = applesmc_read_key(key, buffer, 2);
674 temp = buffer[0]*1000;
675 temp += (buffer[1] >> 6) * 250;
677 mutex_unlock(&applesmc_lock);
682 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
685 static ssize_t applesmc_show_fan_speed(struct device *dev,
686 struct device_attribute *attr, char *sysfsbuf)
689 unsigned int speed = 0;
692 struct sensor_device_attribute_2 *sensor_attr =
693 to_sensor_dev_attr_2(attr);
695 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
696 newkey[1] = '0' + sensor_attr->index;
697 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
698 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
701 mutex_lock(&applesmc_lock);
703 ret = applesmc_read_key(newkey, buffer, 2);
704 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
706 mutex_unlock(&applesmc_lock);
710 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
713 static ssize_t applesmc_store_fan_speed(struct device *dev,
714 struct device_attribute *attr,
715 const char *sysfsbuf, size_t count)
721 struct sensor_device_attribute_2 *sensor_attr =
722 to_sensor_dev_attr_2(attr);
724 speed = simple_strtoul(sysfsbuf, NULL, 10);
726 if (speed > 0x4000) /* Bigger than a 14-bit value */
729 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
730 newkey[1] = '0' + sensor_attr->index;
731 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
732 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
735 mutex_lock(&applesmc_lock);
737 buffer[0] = (speed >> 6) & 0xff;
738 buffer[1] = (speed << 2) & 0xff;
739 ret = applesmc_write_key(newkey, buffer, 2);
741 mutex_unlock(&applesmc_lock);
748 static ssize_t applesmc_show_fan_manual(struct device *dev,
749 struct device_attribute *devattr, char *sysfsbuf)
754 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
756 mutex_lock(&applesmc_lock);
758 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
759 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
761 mutex_unlock(&applesmc_lock);
765 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
768 static ssize_t applesmc_store_fan_manual(struct device *dev,
769 struct device_attribute *devattr,
770 const char *sysfsbuf, size_t count)
776 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
778 input = simple_strtoul(sysfsbuf, NULL, 10);
780 mutex_lock(&applesmc_lock);
782 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
783 val = (buffer[0] << 8 | buffer[1]);
788 val = val | (0x01 << attr->index);
790 val = val & ~(0x01 << attr->index);
792 buffer[0] = (val >> 8) & 0xFF;
793 buffer[1] = val & 0xFF;
795 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
798 mutex_unlock(&applesmc_lock);
805 static ssize_t applesmc_show_fan_position(struct device *dev,
806 struct device_attribute *attr, char *sysfsbuf)
811 struct sensor_device_attribute_2 *sensor_attr =
812 to_sensor_dev_attr_2(attr);
814 newkey[0] = FAN_POSITION[0];
815 newkey[1] = '0' + sensor_attr->index;
816 newkey[2] = FAN_POSITION[2];
817 newkey[3] = FAN_POSITION[3];
820 mutex_lock(&applesmc_lock);
822 ret = applesmc_read_key(newkey, buffer, 16);
825 mutex_unlock(&applesmc_lock);
829 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
832 static ssize_t applesmc_calibrate_show(struct device *dev,
833 struct device_attribute *attr, char *sysfsbuf)
835 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
838 static ssize_t applesmc_calibrate_store(struct device *dev,
839 struct device_attribute *attr, const char *sysfsbuf, size_t count)
841 mutex_lock(&applesmc_lock);
842 applesmc_calibrate();
843 mutex_unlock(&applesmc_lock);
848 static void applesmc_backlight_set(struct work_struct *work)
850 mutex_lock(&applesmc_lock);
851 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
852 mutex_unlock(&applesmc_lock);
854 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
856 static void applesmc_brightness_set(struct led_classdev *led_cdev,
857 enum led_brightness value)
861 backlight_state[0] = value;
862 ret = queue_work(applesmc_led_wq, &backlight_work);
865 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
868 static ssize_t applesmc_key_count_show(struct device *dev,
869 struct device_attribute *attr, char *sysfsbuf)
875 mutex_lock(&applesmc_lock);
877 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
878 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
879 ((u32)buffer[2]<<8) + buffer[3];
881 mutex_unlock(&applesmc_lock);
885 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
888 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
889 struct device_attribute *attr, char *sysfsbuf)
895 mutex_lock(&applesmc_lock);
897 ret = applesmc_get_key_at_index(key_at_index, key);
899 if (ret || !key[0]) {
900 mutex_unlock(&applesmc_lock);
905 ret = applesmc_get_key_type(key, info);
908 mutex_unlock(&applesmc_lock);
914 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
915 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
917 ret = applesmc_read_key(key, sysfsbuf, info[0]);
919 mutex_unlock(&applesmc_lock);
928 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
929 struct device_attribute *attr, char *sysfsbuf)
935 mutex_lock(&applesmc_lock);
937 ret = applesmc_get_key_at_index(key_at_index, key);
939 if (ret || !key[0]) {
940 mutex_unlock(&applesmc_lock);
945 ret = applesmc_get_key_type(key, info);
947 mutex_unlock(&applesmc_lock);
950 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
955 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
956 struct device_attribute *attr, char *sysfsbuf)
962 mutex_lock(&applesmc_lock);
964 ret = applesmc_get_key_at_index(key_at_index, key);
966 if (ret || !key[0]) {
967 mutex_unlock(&applesmc_lock);
972 ret = applesmc_get_key_type(key, info);
974 mutex_unlock(&applesmc_lock);
977 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
982 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
983 struct device_attribute *attr, char *sysfsbuf)
988 mutex_lock(&applesmc_lock);
990 ret = applesmc_get_key_at_index(key_at_index, key);
992 mutex_unlock(&applesmc_lock);
995 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
1000 static ssize_t applesmc_key_at_index_show(struct device *dev,
1001 struct device_attribute *attr, char *sysfsbuf)
1003 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
1006 static ssize_t applesmc_key_at_index_store(struct device *dev,
1007 struct device_attribute *attr, const char *sysfsbuf, size_t count)
1009 mutex_lock(&applesmc_lock);
1011 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
1013 mutex_unlock(&applesmc_lock);
1018 static struct led_classdev applesmc_backlight = {
1019 .name = "smc::kbd_backlight",
1020 .default_trigger = "nand-disk",
1021 .brightness_set = applesmc_brightness_set,
1024 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
1026 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
1027 static DEVICE_ATTR(calibrate, 0644,
1028 applesmc_calibrate_show, applesmc_calibrate_store);
1030 static struct attribute *accelerometer_attributes[] = {
1031 &dev_attr_position.attr,
1032 &dev_attr_calibrate.attr,
1036 static const struct attribute_group accelerometer_attributes_group =
1037 { .attrs = accelerometer_attributes };
1039 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
1041 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
1042 static DEVICE_ATTR(key_at_index, 0644,
1043 applesmc_key_at_index_show, applesmc_key_at_index_store);
1044 static DEVICE_ATTR(key_at_index_name, 0444,
1045 applesmc_key_at_index_name_show, NULL);
1046 static DEVICE_ATTR(key_at_index_type, 0444,
1047 applesmc_key_at_index_type_show, NULL);
1048 static DEVICE_ATTR(key_at_index_data_length, 0444,
1049 applesmc_key_at_index_data_length_show, NULL);
1050 static DEVICE_ATTR(key_at_index_data, 0444,
1051 applesmc_key_at_index_read_show, NULL);
1053 static struct attribute *key_enumeration_attributes[] = {
1054 &dev_attr_key_count.attr,
1055 &dev_attr_key_at_index.attr,
1056 &dev_attr_key_at_index_name.attr,
1057 &dev_attr_key_at_index_type.attr,
1058 &dev_attr_key_at_index_data_length.attr,
1059 &dev_attr_key_at_index_data.attr,
1063 static const struct attribute_group key_enumeration_group =
1064 { .attrs = key_enumeration_attributes };
1067 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1068 * - show actual speed
1069 * - show/store minimum speed
1070 * - show maximum speed
1072 * - show/store target speed
1073 * - show/store manual mode
1075 #define sysfs_fan_speeds_offset(offset) \
1076 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1077 applesmc_show_fan_speed, NULL, 0, offset-1); \
1079 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1080 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1082 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1083 applesmc_show_fan_speed, NULL, 2, offset-1); \
1085 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1086 applesmc_show_fan_speed, NULL, 3, offset-1); \
1088 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1089 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1091 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1092 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1094 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1095 applesmc_show_fan_position, NULL, offset-1); \
1097 static struct attribute *fan##offset##_attributes[] = { \
1098 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1099 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1100 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1101 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1102 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1103 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1104 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1109 * Create the needed functions for each fan using the macro defined above
1110 * (4 fans are supported)
1112 sysfs_fan_speeds_offset(1);
1113 sysfs_fan_speeds_offset(2);
1114 sysfs_fan_speeds_offset(3);
1115 sysfs_fan_speeds_offset(4);
1117 static const struct attribute_group fan_attribute_groups[] = {
1118 { .attrs = fan1_attributes },
1119 { .attrs = fan2_attributes },
1120 { .attrs = fan3_attributes },
1121 { .attrs = fan4_attributes },
1125 * Temperature sensors sysfs entries.
1127 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1128 applesmc_show_temperature, NULL, 0);
1129 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1130 applesmc_show_temperature, NULL, 1);
1131 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1132 applesmc_show_temperature, NULL, 2);
1133 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1134 applesmc_show_temperature, NULL, 3);
1135 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1136 applesmc_show_temperature, NULL, 4);
1137 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1138 applesmc_show_temperature, NULL, 5);
1139 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1140 applesmc_show_temperature, NULL, 6);
1141 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1142 applesmc_show_temperature, NULL, 7);
1143 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1144 applesmc_show_temperature, NULL, 8);
1145 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1146 applesmc_show_temperature, NULL, 9);
1147 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1148 applesmc_show_temperature, NULL, 10);
1149 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1150 applesmc_show_temperature, NULL, 11);
1151 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1152 applesmc_show_temperature, NULL, 12);
1153 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1154 applesmc_show_temperature, NULL, 13);
1155 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1156 applesmc_show_temperature, NULL, 14);
1157 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1158 applesmc_show_temperature, NULL, 15);
1159 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1160 applesmc_show_temperature, NULL, 16);
1161 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1162 applesmc_show_temperature, NULL, 17);
1163 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1164 applesmc_show_temperature, NULL, 18);
1165 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1166 applesmc_show_temperature, NULL, 19);
1167 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1168 applesmc_show_temperature, NULL, 20);
1169 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1170 applesmc_show_temperature, NULL, 21);
1171 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1172 applesmc_show_temperature, NULL, 22);
1173 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1174 applesmc_show_temperature, NULL, 23);
1175 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1176 applesmc_show_temperature, NULL, 24);
1177 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1178 applesmc_show_temperature, NULL, 25);
1179 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1180 applesmc_show_temperature, NULL, 26);
1181 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1182 applesmc_show_temperature, NULL, 27);
1183 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1184 applesmc_show_temperature, NULL, 28);
1185 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1186 applesmc_show_temperature, NULL, 29);
1187 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1188 applesmc_show_temperature, NULL, 30);
1189 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1190 applesmc_show_temperature, NULL, 31);
1191 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1192 applesmc_show_temperature, NULL, 32);
1193 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1194 applesmc_show_temperature, NULL, 33);
1195 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1196 applesmc_show_temperature, NULL, 34);
1197 static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
1198 applesmc_show_temperature, NULL, 35);
1199 static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
1200 applesmc_show_temperature, NULL, 36);
1201 static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
1202 applesmc_show_temperature, NULL, 37);
1203 static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
1204 applesmc_show_temperature, NULL, 38);
1205 static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
1206 applesmc_show_temperature, NULL, 39);
1208 static struct attribute *temperature_attributes[] = {
1209 &sensor_dev_attr_temp1_input.dev_attr.attr,
1210 &sensor_dev_attr_temp2_input.dev_attr.attr,
1211 &sensor_dev_attr_temp3_input.dev_attr.attr,
1212 &sensor_dev_attr_temp4_input.dev_attr.attr,
1213 &sensor_dev_attr_temp5_input.dev_attr.attr,
1214 &sensor_dev_attr_temp6_input.dev_attr.attr,
1215 &sensor_dev_attr_temp7_input.dev_attr.attr,
1216 &sensor_dev_attr_temp8_input.dev_attr.attr,
1217 &sensor_dev_attr_temp9_input.dev_attr.attr,
1218 &sensor_dev_attr_temp10_input.dev_attr.attr,
1219 &sensor_dev_attr_temp11_input.dev_attr.attr,
1220 &sensor_dev_attr_temp12_input.dev_attr.attr,
1221 &sensor_dev_attr_temp13_input.dev_attr.attr,
1222 &sensor_dev_attr_temp14_input.dev_attr.attr,
1223 &sensor_dev_attr_temp15_input.dev_attr.attr,
1224 &sensor_dev_attr_temp16_input.dev_attr.attr,
1225 &sensor_dev_attr_temp17_input.dev_attr.attr,
1226 &sensor_dev_attr_temp18_input.dev_attr.attr,
1227 &sensor_dev_attr_temp19_input.dev_attr.attr,
1228 &sensor_dev_attr_temp20_input.dev_attr.attr,
1229 &sensor_dev_attr_temp21_input.dev_attr.attr,
1230 &sensor_dev_attr_temp22_input.dev_attr.attr,
1231 &sensor_dev_attr_temp23_input.dev_attr.attr,
1232 &sensor_dev_attr_temp24_input.dev_attr.attr,
1233 &sensor_dev_attr_temp25_input.dev_attr.attr,
1234 &sensor_dev_attr_temp26_input.dev_attr.attr,
1235 &sensor_dev_attr_temp27_input.dev_attr.attr,
1236 &sensor_dev_attr_temp28_input.dev_attr.attr,
1237 &sensor_dev_attr_temp29_input.dev_attr.attr,
1238 &sensor_dev_attr_temp30_input.dev_attr.attr,
1239 &sensor_dev_attr_temp31_input.dev_attr.attr,
1240 &sensor_dev_attr_temp32_input.dev_attr.attr,
1241 &sensor_dev_attr_temp33_input.dev_attr.attr,
1242 &sensor_dev_attr_temp34_input.dev_attr.attr,
1243 &sensor_dev_attr_temp35_input.dev_attr.attr,
1244 &sensor_dev_attr_temp36_input.dev_attr.attr,
1245 &sensor_dev_attr_temp37_input.dev_attr.attr,
1246 &sensor_dev_attr_temp38_input.dev_attr.attr,
1247 &sensor_dev_attr_temp39_input.dev_attr.attr,
1248 &sensor_dev_attr_temp40_input.dev_attr.attr,
1252 static const struct attribute_group temperature_attributes_group =
1253 { .attrs = temperature_attributes };
1258 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1260 static int applesmc_dmi_match(const struct dmi_system_id *id)
1263 struct dmi_match_data* dmi_data = id->driver_data;
1264 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1265 applesmc_accelerometer = dmi_data->accelerometer;
1266 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1267 applesmc_accelerometer ? "with" : "without");
1268 applesmc_light = dmi_data->light;
1269 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1270 applesmc_light ? "with" : "without");
1272 applesmc_temperature_set = dmi_data->temperature_set;
1273 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1275 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1279 /* Create accelerometer ressources */
1280 static int applesmc_create_accelerometer(void)
1282 struct input_dev *idev;
1285 ret = sysfs_create_group(&pdev->dev.kobj,
1286 &accelerometer_attributes_group);
1290 applesmc_idev = input_allocate_polled_device();
1291 if (!applesmc_idev) {
1296 applesmc_idev->poll = applesmc_idev_poll;
1297 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1299 /* initial calibrate for the input device */
1300 applesmc_calibrate();
1302 /* initialize the input device */
1303 idev = applesmc_idev->input;
1304 idev->name = "applesmc";
1305 idev->id.bustype = BUS_HOST;
1306 idev->dev.parent = &pdev->dev;
1307 idev->evbit[0] = BIT_MASK(EV_ABS);
1308 input_set_abs_params(idev, ABS_X,
1309 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1310 input_set_abs_params(idev, ABS_Y,
1311 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1313 ret = input_register_polled_device(applesmc_idev);
1320 input_free_polled_device(applesmc_idev);
1323 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1326 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1330 /* Release all ressources used by the accelerometer */
1331 static void applesmc_release_accelerometer(void)
1333 input_unregister_polled_device(applesmc_idev);
1334 input_free_polled_device(applesmc_idev);
1335 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1338 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1339 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1340 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1341 /* MacBook2: accelerometer and temperature set 1 */
1342 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1343 /* MacBook: accelerometer and temperature set 2 */
1344 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1345 /* MacMini: temperature set 3 */
1346 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1347 /* MacPro: temperature set 4 */
1348 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1349 /* iMac: temperature set 5 */
1350 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1351 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1352 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1353 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1354 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1355 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1356 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1357 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1358 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1359 /* iMac 5: light sensor only, temperature set 10 */
1360 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1361 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1362 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
1363 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1364 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
1365 /* iMac 8: light sensor only, temperature set 13 */
1366 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
1367 /* iMac 6: light sensor only, temperature set 14 */
1368 { .accelerometer = 0, .light = 0, .temperature_set = 14 },
1369 /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
1370 { .accelerometer = 1, .light = 1, .temperature_set = 15 },
1371 /* MacPro3,1: temperature set 16 */
1372 { .accelerometer = 0, .light = 0, .temperature_set = 16 },
1373 /* iMac 9,1: light sensor only, temperature set 17 */
1374 { .accelerometer = 0, .light = 0, .temperature_set = 17 },
1375 /* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
1376 { .accelerometer = 1, .light = 1, .temperature_set = 18 },
1377 /* MacBook Pro 5,3: accelerometer, backlight and temperature set 19 */
1378 { .accelerometer = 1, .light = 1, .temperature_set = 19 },
1379 /* MacBook Pro 5,4: accelerometer, backlight and temperature set 20 */
1380 { .accelerometer = 1, .light = 1, .temperature_set = 20 },
1381 /* MacBook Pro 6,2: accelerometer, backlight and temperature set 21 */
1382 { .accelerometer = 1, .light = 1, .temperature_set = 21 },
1385 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1386 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1387 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1388 { applesmc_dmi_match, "Apple MacBook Air 2", {
1389 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1390 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
1391 &applesmc_dmi_data[15]},
1392 { applesmc_dmi_match, "Apple MacBook Air", {
1393 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1394 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1395 &applesmc_dmi_data[7]},
1396 { applesmc_dmi_match, "Apple MacBook Pro 5,4", {
1397 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1398 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4") },
1399 &applesmc_dmi_data[20]},
1400 { applesmc_dmi_match, "Apple MacBook Pro 5,3", {
1401 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1402 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3") },
1403 &applesmc_dmi_data[19]},
1404 { applesmc_dmi_match, "Apple MacBook Pro 6", {
1405 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1406 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6") },
1407 &applesmc_dmi_data[21]},
1408 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1409 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1410 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1411 &applesmc_dmi_data[12]},
1412 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1413 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1414 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1415 &applesmc_dmi_data[8]},
1416 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1417 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1418 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1419 &applesmc_dmi_data[9]},
1420 { applesmc_dmi_match, "Apple MacBook Pro 2,2", {
1421 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
1422 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
1423 &applesmc_dmi_data[18]},
1424 { applesmc_dmi_match, "Apple MacBook Pro", {
1425 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1426 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1427 &applesmc_dmi_data[0]},
1428 { applesmc_dmi_match, "Apple MacBook (v2)", {
1429 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1430 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1431 &applesmc_dmi_data[1]},
1432 { applesmc_dmi_match, "Apple MacBook (v3)", {
1433 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1434 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1435 &applesmc_dmi_data[6]},
1436 { applesmc_dmi_match, "Apple MacBook 4", {
1437 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1438 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1439 &applesmc_dmi_data[6]},
1440 { applesmc_dmi_match, "Apple MacBook 5", {
1441 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1442 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1443 &applesmc_dmi_data[11]},
1444 { applesmc_dmi_match, "Apple MacBook", {
1445 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1446 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1447 &applesmc_dmi_data[2]},
1448 { applesmc_dmi_match, "Apple Macmini", {
1449 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1450 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1451 &applesmc_dmi_data[3]},
1452 { applesmc_dmi_match, "Apple MacPro2", {
1453 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1454 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1455 &applesmc_dmi_data[4]},
1456 { applesmc_dmi_match, "Apple MacPro3", {
1457 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1458 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") },
1459 &applesmc_dmi_data[16]},
1460 { applesmc_dmi_match, "Apple MacPro", {
1461 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1462 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1463 &applesmc_dmi_data[4]},
1464 { applesmc_dmi_match, "Apple iMac 9,1", {
1465 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
1466 DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
1467 &applesmc_dmi_data[17]},
1468 { applesmc_dmi_match, "Apple iMac 8", {
1469 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1470 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1471 &applesmc_dmi_data[13]},
1472 { applesmc_dmi_match, "Apple iMac 6", {
1473 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1474 DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
1475 &applesmc_dmi_data[14]},
1476 { applesmc_dmi_match, "Apple iMac 5", {
1477 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1478 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1479 &applesmc_dmi_data[10]},
1480 { applesmc_dmi_match, "Apple iMac", {
1481 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1482 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1483 &applesmc_dmi_data[5]},
1487 static int __init applesmc_init(void)
1493 if (!dmi_check_system(applesmc_whitelist)) {
1494 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1499 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1505 ret = platform_driver_register(&applesmc_driver);
1509 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1512 ret = PTR_ERR(pdev);
1516 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1520 /* Create key enumeration sysfs files */
1521 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1525 /* create fan files */
1526 count = applesmc_get_fan_count();
1528 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1530 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1534 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1535 " but at most 4 fans are supported"
1536 " by the driver.\n");
1539 while (fans_handled < count) {
1540 ret = sysfs_create_group(&pdev->dev.kobj,
1541 &fan_attribute_groups[fans_handled]);
1548 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1550 if (temperature_attributes[i] == NULL) {
1551 printk(KERN_ERR "applesmc: More temperature sensors "
1552 "in temperature_sensors_sets (at least %i)"
1553 "than available sysfs files in "
1554 "temperature_attributes (%i), please report "
1555 "this bug.\n", i, i-1);
1556 goto out_temperature;
1558 ret = sysfs_create_file(&pdev->dev.kobj,
1559 temperature_attributes[i]);
1561 goto out_temperature;
1564 if (applesmc_accelerometer) {
1565 ret = applesmc_create_accelerometer();
1567 goto out_temperature;
1570 if (applesmc_light) {
1571 /* Add light sensor file */
1572 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1574 goto out_accelerometer;
1576 /* Create the workqueue */
1577 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1578 if (!applesmc_led_wq) {
1580 goto out_light_sysfs;
1583 /* register as a led device */
1584 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1589 hwmon_dev = hwmon_device_register(&pdev->dev);
1590 if (IS_ERR(hwmon_dev)) {
1591 ret = PTR_ERR(hwmon_dev);
1592 goto out_light_ledclass;
1595 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1601 led_classdev_unregister(&applesmc_backlight);
1604 destroy_workqueue(applesmc_led_wq);
1607 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1609 if (applesmc_accelerometer)
1610 applesmc_release_accelerometer();
1612 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1614 while (fans_handled)
1615 sysfs_remove_group(&pdev->dev.kobj,
1616 &fan_attribute_groups[--fans_handled]);
1617 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1619 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1621 platform_device_unregister(pdev);
1623 platform_driver_unregister(&applesmc_driver);
1625 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1627 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1631 static void __exit applesmc_exit(void)
1633 hwmon_device_unregister(hwmon_dev);
1634 if (applesmc_light) {
1635 led_classdev_unregister(&applesmc_backlight);
1636 destroy_workqueue(applesmc_led_wq);
1637 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1639 if (applesmc_accelerometer)
1640 applesmc_release_accelerometer();
1641 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1642 while (fans_handled)
1643 sysfs_remove_group(&pdev->dev.kobj,
1644 &fan_attribute_groups[--fans_handled]);
1645 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1646 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1647 platform_device_unregister(pdev);
1648 platform_driver_unregister(&applesmc_driver);
1649 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1651 printk(KERN_INFO "applesmc: driver unloaded.\n");
1654 module_init(applesmc_init);
1655 module_exit(applesmc_exit);
1657 MODULE_AUTHOR("Nicolas Boichat");
1658 MODULE_DESCRIPTION("Apple SMC");
1659 MODULE_LICENSE("GPL v2");
1660 MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);