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 },
162 /* Set 22: MacBook Pro 7,1 */
163 { "TB0T", "TB1T", "TB2T", "TC0D", "TC0P", "TN0D", "TN0P", "TN0S",
164 "TN1D", "TN1F", "TN1G", "TN1S", "Th1H", "Ts0P", "Ts0S", NULL },
167 /* List of keys used to read/write fan speeds */
168 static const char* fan_speed_keys[] = {
176 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
177 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
179 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
180 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
181 #define APPLESMC_INPUT_FLAT 4
187 /* Structure to be passed to DMI_MATCH function */
188 struct dmi_match_data {
189 /* Indicates whether this computer has an accelerometer. */
191 /* Indicates whether this computer has light sensors and keyboard backlight. */
193 /* Indicates which temperature sensors set to use. */
197 static const int debug;
198 static struct platform_device *pdev;
201 static u8 backlight_state[2];
203 static struct device *hwmon_dev;
204 static struct input_polled_dev *applesmc_idev;
206 /* Indicates whether this computer has an accelerometer. */
207 static unsigned int applesmc_accelerometer;
209 /* Indicates whether this computer has light sensors and keyboard backlight. */
210 static unsigned int applesmc_light;
212 /* The number of fans handled by the driver */
213 static unsigned int fans_handled;
215 /* Indicates which temperature sensors set to use. */
216 static unsigned int applesmc_temperature_set;
218 static DEFINE_MUTEX(applesmc_lock);
221 * Last index written to key_at_index sysfs file, and value to use for all other
222 * key_at_index_* sysfs files.
224 static unsigned int key_at_index;
226 static struct workqueue_struct *applesmc_led_wq;
229 * __wait_status - Wait up to 32ms for the status port to get a certain value
230 * (masked with 0x0f), returning zero if the value is obtained. Callers must
231 * hold applesmc_lock.
233 static int __wait_status(u8 val)
237 val = val & APPLESMC_STATUS_MASK;
239 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
241 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
244 "Waited %d us for status %x\n",
245 2 * us - APPLESMC_MIN_WAIT, val);
250 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
251 val, inb(APPLESMC_CMD_PORT));
257 * special treatment of command port - on newer macbooks, it seems necessary
258 * to resend the command byte before polling the status again. Callers must
259 * hold applesmc_lock.
261 static int send_command(u8 cmd)
264 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
265 outb(cmd, APPLESMC_CMD_PORT);
267 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
270 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
271 cmd, inb(APPLESMC_CMD_PORT));
276 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
277 * Returns zero on success or a negative error on failure. Callers must
278 * hold applesmc_lock.
280 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
284 if (len > APPLESMC_MAX_DATA_LENGTH) {
285 printk(KERN_ERR "applesmc_read_key: cannot read more than "
286 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
290 if (send_command(APPLESMC_READ_CMD))
293 for (i = 0; i < 4; i++) {
294 outb(key[i], APPLESMC_DATA_PORT);
295 if (__wait_status(0x04))
299 printk(KERN_DEBUG "<%s", key);
301 outb(len, APPLESMC_DATA_PORT);
303 printk(KERN_DEBUG ">%x", len);
305 for (i = 0; i < len; i++) {
306 if (__wait_status(0x05))
308 buffer[i] = inb(APPLESMC_DATA_PORT);
310 printk(KERN_DEBUG "<%x", buffer[i]);
313 printk(KERN_DEBUG "\n");
319 * applesmc_write_key - writes len bytes from buffer to a given key.
320 * Returns zero on success or a negative error on failure. Callers must
321 * hold applesmc_lock.
323 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
327 if (len > APPLESMC_MAX_DATA_LENGTH) {
328 printk(KERN_ERR "applesmc_write_key: cannot write more than "
329 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
333 if (send_command(APPLESMC_WRITE_CMD))
336 for (i = 0; i < 4; i++) {
337 outb(key[i], APPLESMC_DATA_PORT);
338 if (__wait_status(0x04))
342 outb(len, APPLESMC_DATA_PORT);
344 for (i = 0; i < len; i++) {
345 if (__wait_status(0x04))
347 outb(buffer[i], APPLESMC_DATA_PORT);
354 * applesmc_get_key_at_index - get key at index, and put the result in key
355 * (char[6]). Returns zero on success or a negative error on failure. Callers
356 * must hold applesmc_lock.
358 static int applesmc_get_key_at_index(int index, char* key)
362 readkey[0] = index >> 24;
363 readkey[1] = index >> 16;
364 readkey[2] = index >> 8;
367 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
370 for (i = 0; i < 4; i++) {
371 outb(readkey[i], APPLESMC_DATA_PORT);
372 if (__wait_status(0x04))
376 outb(4, APPLESMC_DATA_PORT);
378 for (i = 0; i < 4; i++) {
379 if (__wait_status(0x05))
381 key[i] = inb(APPLESMC_DATA_PORT);
389 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
390 * Returns zero on success or a negative error on failure. Callers must
391 * hold applesmc_lock.
393 static int applesmc_get_key_type(char* key, char* type)
397 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
400 for (i = 0; i < 4; i++) {
401 outb(key[i], APPLESMC_DATA_PORT);
402 if (__wait_status(0x04))
406 outb(6, APPLESMC_DATA_PORT);
408 for (i = 0; i < 6; i++) {
409 if (__wait_status(0x05))
411 type[i] = inb(APPLESMC_DATA_PORT);
419 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
420 * hold applesmc_lock.
422 static int applesmc_read_motion_sensor(int index, s16* value)
429 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
432 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
435 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
441 *value = ((s16)buffer[0] << 8) | buffer[1];
447 * applesmc_device_init - initialize the accelerometer. Returns zero on success
448 * and negative error code on failure. Can sleep.
450 static int applesmc_device_init(void)
452 int total, ret = -ENXIO;
455 if (!applesmc_accelerometer)
458 mutex_lock(&applesmc_lock);
460 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
462 printk(KERN_DEBUG "applesmc try %d\n", total);
463 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
464 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
465 if (total == INIT_TIMEOUT_MSECS) {
466 printk(KERN_DEBUG "applesmc: device has"
467 " already been initialized"
468 " (0x%02x, 0x%02x).\n",
469 buffer[0], buffer[1]);
471 printk(KERN_DEBUG "applesmc: device"
472 " successfully initialized"
473 " (0x%02x, 0x%02x).\n",
474 buffer[0], buffer[1]);
481 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
482 msleep(INIT_WAIT_MSECS);
485 printk(KERN_WARNING "applesmc: failed to init the device\n");
488 mutex_unlock(&applesmc_lock);
493 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
496 static int applesmc_get_fan_count(void)
501 mutex_lock(&applesmc_lock);
503 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
505 mutex_unlock(&applesmc_lock);
512 /* Device model stuff */
513 static int applesmc_probe(struct platform_device *dev)
517 ret = applesmc_device_init();
521 printk(KERN_INFO "applesmc: device successfully initialized.\n");
525 /* Synchronize device with memorized backlight state */
526 static int applesmc_pm_resume(struct device *dev)
528 mutex_lock(&applesmc_lock);
530 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
531 mutex_unlock(&applesmc_lock);
535 /* Reinitialize device on resume from hibernation */
536 static int applesmc_pm_restore(struct device *dev)
538 int ret = applesmc_device_init();
541 return applesmc_pm_resume(dev);
544 static const struct dev_pm_ops applesmc_pm_ops = {
545 .resume = applesmc_pm_resume,
546 .restore = applesmc_pm_restore,
549 static struct platform_driver applesmc_driver = {
550 .probe = applesmc_probe,
553 .owner = THIS_MODULE,
554 .pm = &applesmc_pm_ops,
559 * applesmc_calibrate - Set our "resting" values. Callers must
560 * hold applesmc_lock.
562 static void applesmc_calibrate(void)
564 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
565 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
569 static void applesmc_idev_poll(struct input_polled_dev *dev)
571 struct input_dev *idev = dev->input;
574 mutex_lock(&applesmc_lock);
576 if (applesmc_read_motion_sensor(SENSOR_X, &x))
578 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
582 input_report_abs(idev, ABS_X, x - rest_x);
583 input_report_abs(idev, ABS_Y, y - rest_y);
587 mutex_unlock(&applesmc_lock);
592 static ssize_t applesmc_name_show(struct device *dev,
593 struct device_attribute *attr, char *buf)
595 return snprintf(buf, PAGE_SIZE, "applesmc\n");
598 static ssize_t applesmc_position_show(struct device *dev,
599 struct device_attribute *attr, char *buf)
604 mutex_lock(&applesmc_lock);
606 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
609 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
612 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
617 mutex_unlock(&applesmc_lock);
621 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
624 static ssize_t applesmc_light_show(struct device *dev,
625 struct device_attribute *attr, char *sysfsbuf)
627 static int data_length;
629 u8 left = 0, right = 0;
630 u8 buffer[10], query[6];
632 mutex_lock(&applesmc_lock);
635 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
638 data_length = clamp_val(query[0], 0, 10);
639 printk(KERN_INFO "applesmc: light sensor data length set to "
640 "%d\n", data_length);
643 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
644 /* newer macbooks report a single 10-bit bigendian value */
645 if (data_length == 10) {
646 left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2;
652 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
656 mutex_unlock(&applesmc_lock);
660 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
663 /* Displays degree Celsius * 1000 */
664 static ssize_t applesmc_show_temperature(struct device *dev,
665 struct device_attribute *devattr, char *sysfsbuf)
670 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
672 temperature_sensors_sets[applesmc_temperature_set][attr->index];
674 mutex_lock(&applesmc_lock);
676 ret = applesmc_read_key(key, buffer, 2);
677 temp = buffer[0]*1000;
678 temp += (buffer[1] >> 6) * 250;
680 mutex_unlock(&applesmc_lock);
685 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
688 static ssize_t applesmc_show_fan_speed(struct device *dev,
689 struct device_attribute *attr, char *sysfsbuf)
692 unsigned int speed = 0;
695 struct sensor_device_attribute_2 *sensor_attr =
696 to_sensor_dev_attr_2(attr);
698 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
699 newkey[1] = '0' + sensor_attr->index;
700 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
701 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
704 mutex_lock(&applesmc_lock);
706 ret = applesmc_read_key(newkey, buffer, 2);
707 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
709 mutex_unlock(&applesmc_lock);
713 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
716 static ssize_t applesmc_store_fan_speed(struct device *dev,
717 struct device_attribute *attr,
718 const char *sysfsbuf, size_t count)
724 struct sensor_device_attribute_2 *sensor_attr =
725 to_sensor_dev_attr_2(attr);
727 speed = simple_strtoul(sysfsbuf, NULL, 10);
729 if (speed > 0x4000) /* Bigger than a 14-bit value */
732 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
733 newkey[1] = '0' + sensor_attr->index;
734 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
735 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
738 mutex_lock(&applesmc_lock);
740 buffer[0] = (speed >> 6) & 0xff;
741 buffer[1] = (speed << 2) & 0xff;
742 ret = applesmc_write_key(newkey, buffer, 2);
744 mutex_unlock(&applesmc_lock);
751 static ssize_t applesmc_show_fan_manual(struct device *dev,
752 struct device_attribute *devattr, char *sysfsbuf)
757 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
759 mutex_lock(&applesmc_lock);
761 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
762 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
764 mutex_unlock(&applesmc_lock);
768 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
771 static ssize_t applesmc_store_fan_manual(struct device *dev,
772 struct device_attribute *devattr,
773 const char *sysfsbuf, size_t count)
779 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
781 input = simple_strtoul(sysfsbuf, NULL, 10);
783 mutex_lock(&applesmc_lock);
785 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
786 val = (buffer[0] << 8 | buffer[1]);
791 val = val | (0x01 << attr->index);
793 val = val & ~(0x01 << attr->index);
795 buffer[0] = (val >> 8) & 0xFF;
796 buffer[1] = val & 0xFF;
798 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
801 mutex_unlock(&applesmc_lock);
808 static ssize_t applesmc_show_fan_position(struct device *dev,
809 struct device_attribute *attr, char *sysfsbuf)
814 struct sensor_device_attribute_2 *sensor_attr =
815 to_sensor_dev_attr_2(attr);
817 newkey[0] = FAN_POSITION[0];
818 newkey[1] = '0' + sensor_attr->index;
819 newkey[2] = FAN_POSITION[2];
820 newkey[3] = FAN_POSITION[3];
823 mutex_lock(&applesmc_lock);
825 ret = applesmc_read_key(newkey, buffer, 16);
828 mutex_unlock(&applesmc_lock);
832 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
835 static ssize_t applesmc_calibrate_show(struct device *dev,
836 struct device_attribute *attr, char *sysfsbuf)
838 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
841 static ssize_t applesmc_calibrate_store(struct device *dev,
842 struct device_attribute *attr, const char *sysfsbuf, size_t count)
844 mutex_lock(&applesmc_lock);
845 applesmc_calibrate();
846 mutex_unlock(&applesmc_lock);
851 static void applesmc_backlight_set(struct work_struct *work)
853 mutex_lock(&applesmc_lock);
854 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
855 mutex_unlock(&applesmc_lock);
857 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
859 static void applesmc_brightness_set(struct led_classdev *led_cdev,
860 enum led_brightness value)
864 backlight_state[0] = value;
865 ret = queue_work(applesmc_led_wq, &backlight_work);
868 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
871 static ssize_t applesmc_key_count_show(struct device *dev,
872 struct device_attribute *attr, char *sysfsbuf)
878 mutex_lock(&applesmc_lock);
880 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
881 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
882 ((u32)buffer[2]<<8) + buffer[3];
884 mutex_unlock(&applesmc_lock);
888 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
891 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
892 struct device_attribute *attr, char *sysfsbuf)
898 mutex_lock(&applesmc_lock);
900 ret = applesmc_get_key_at_index(key_at_index, key);
902 if (ret || !key[0]) {
903 mutex_unlock(&applesmc_lock);
908 ret = applesmc_get_key_type(key, info);
911 mutex_unlock(&applesmc_lock);
917 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
918 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
920 ret = applesmc_read_key(key, sysfsbuf, info[0]);
922 mutex_unlock(&applesmc_lock);
931 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
932 struct device_attribute *attr, char *sysfsbuf)
938 mutex_lock(&applesmc_lock);
940 ret = applesmc_get_key_at_index(key_at_index, key);
942 if (ret || !key[0]) {
943 mutex_unlock(&applesmc_lock);
948 ret = applesmc_get_key_type(key, info);
950 mutex_unlock(&applesmc_lock);
953 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
958 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
959 struct device_attribute *attr, char *sysfsbuf)
965 mutex_lock(&applesmc_lock);
967 ret = applesmc_get_key_at_index(key_at_index, key);
969 if (ret || !key[0]) {
970 mutex_unlock(&applesmc_lock);
975 ret = applesmc_get_key_type(key, info);
977 mutex_unlock(&applesmc_lock);
980 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
985 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
986 struct device_attribute *attr, char *sysfsbuf)
991 mutex_lock(&applesmc_lock);
993 ret = applesmc_get_key_at_index(key_at_index, key);
995 mutex_unlock(&applesmc_lock);
998 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
1003 static ssize_t applesmc_key_at_index_show(struct device *dev,
1004 struct device_attribute *attr, char *sysfsbuf)
1006 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
1009 static ssize_t applesmc_key_at_index_store(struct device *dev,
1010 struct device_attribute *attr, const char *sysfsbuf, size_t count)
1012 mutex_lock(&applesmc_lock);
1014 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
1016 mutex_unlock(&applesmc_lock);
1021 static struct led_classdev applesmc_backlight = {
1022 .name = "smc::kbd_backlight",
1023 .default_trigger = "nand-disk",
1024 .brightness_set = applesmc_brightness_set,
1027 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
1029 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
1030 static DEVICE_ATTR(calibrate, 0644,
1031 applesmc_calibrate_show, applesmc_calibrate_store);
1033 static struct attribute *accelerometer_attributes[] = {
1034 &dev_attr_position.attr,
1035 &dev_attr_calibrate.attr,
1039 static const struct attribute_group accelerometer_attributes_group =
1040 { .attrs = accelerometer_attributes };
1042 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
1044 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
1045 static DEVICE_ATTR(key_at_index, 0644,
1046 applesmc_key_at_index_show, applesmc_key_at_index_store);
1047 static DEVICE_ATTR(key_at_index_name, 0444,
1048 applesmc_key_at_index_name_show, NULL);
1049 static DEVICE_ATTR(key_at_index_type, 0444,
1050 applesmc_key_at_index_type_show, NULL);
1051 static DEVICE_ATTR(key_at_index_data_length, 0444,
1052 applesmc_key_at_index_data_length_show, NULL);
1053 static DEVICE_ATTR(key_at_index_data, 0444,
1054 applesmc_key_at_index_read_show, NULL);
1056 static struct attribute *key_enumeration_attributes[] = {
1057 &dev_attr_key_count.attr,
1058 &dev_attr_key_at_index.attr,
1059 &dev_attr_key_at_index_name.attr,
1060 &dev_attr_key_at_index_type.attr,
1061 &dev_attr_key_at_index_data_length.attr,
1062 &dev_attr_key_at_index_data.attr,
1066 static const struct attribute_group key_enumeration_group =
1067 { .attrs = key_enumeration_attributes };
1070 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1071 * - show actual speed
1072 * - show/store minimum speed
1073 * - show maximum speed
1075 * - show/store target speed
1076 * - show/store manual mode
1078 #define sysfs_fan_speeds_offset(offset) \
1079 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1080 applesmc_show_fan_speed, NULL, 0, offset-1); \
1082 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1083 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1085 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1086 applesmc_show_fan_speed, NULL, 2, offset-1); \
1088 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1089 applesmc_show_fan_speed, NULL, 3, offset-1); \
1091 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1092 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1094 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1095 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1097 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1098 applesmc_show_fan_position, NULL, offset-1); \
1100 static struct attribute *fan##offset##_attributes[] = { \
1101 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1102 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1103 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1104 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1105 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1106 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1107 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1112 * Create the needed functions for each fan using the macro defined above
1113 * (4 fans are supported)
1115 sysfs_fan_speeds_offset(1);
1116 sysfs_fan_speeds_offset(2);
1117 sysfs_fan_speeds_offset(3);
1118 sysfs_fan_speeds_offset(4);
1120 static const struct attribute_group fan_attribute_groups[] = {
1121 { .attrs = fan1_attributes },
1122 { .attrs = fan2_attributes },
1123 { .attrs = fan3_attributes },
1124 { .attrs = fan4_attributes },
1128 * Temperature sensors sysfs entries.
1130 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1131 applesmc_show_temperature, NULL, 0);
1132 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1133 applesmc_show_temperature, NULL, 1);
1134 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1135 applesmc_show_temperature, NULL, 2);
1136 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1137 applesmc_show_temperature, NULL, 3);
1138 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1139 applesmc_show_temperature, NULL, 4);
1140 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1141 applesmc_show_temperature, NULL, 5);
1142 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1143 applesmc_show_temperature, NULL, 6);
1144 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1145 applesmc_show_temperature, NULL, 7);
1146 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1147 applesmc_show_temperature, NULL, 8);
1148 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1149 applesmc_show_temperature, NULL, 9);
1150 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1151 applesmc_show_temperature, NULL, 10);
1152 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1153 applesmc_show_temperature, NULL, 11);
1154 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1155 applesmc_show_temperature, NULL, 12);
1156 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1157 applesmc_show_temperature, NULL, 13);
1158 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1159 applesmc_show_temperature, NULL, 14);
1160 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1161 applesmc_show_temperature, NULL, 15);
1162 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1163 applesmc_show_temperature, NULL, 16);
1164 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1165 applesmc_show_temperature, NULL, 17);
1166 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1167 applesmc_show_temperature, NULL, 18);
1168 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1169 applesmc_show_temperature, NULL, 19);
1170 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1171 applesmc_show_temperature, NULL, 20);
1172 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1173 applesmc_show_temperature, NULL, 21);
1174 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1175 applesmc_show_temperature, NULL, 22);
1176 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1177 applesmc_show_temperature, NULL, 23);
1178 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1179 applesmc_show_temperature, NULL, 24);
1180 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1181 applesmc_show_temperature, NULL, 25);
1182 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1183 applesmc_show_temperature, NULL, 26);
1184 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1185 applesmc_show_temperature, NULL, 27);
1186 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1187 applesmc_show_temperature, NULL, 28);
1188 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1189 applesmc_show_temperature, NULL, 29);
1190 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1191 applesmc_show_temperature, NULL, 30);
1192 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1193 applesmc_show_temperature, NULL, 31);
1194 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1195 applesmc_show_temperature, NULL, 32);
1196 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1197 applesmc_show_temperature, NULL, 33);
1198 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1199 applesmc_show_temperature, NULL, 34);
1200 static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
1201 applesmc_show_temperature, NULL, 35);
1202 static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
1203 applesmc_show_temperature, NULL, 36);
1204 static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
1205 applesmc_show_temperature, NULL, 37);
1206 static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
1207 applesmc_show_temperature, NULL, 38);
1208 static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
1209 applesmc_show_temperature, NULL, 39);
1211 static struct attribute *temperature_attributes[] = {
1212 &sensor_dev_attr_temp1_input.dev_attr.attr,
1213 &sensor_dev_attr_temp2_input.dev_attr.attr,
1214 &sensor_dev_attr_temp3_input.dev_attr.attr,
1215 &sensor_dev_attr_temp4_input.dev_attr.attr,
1216 &sensor_dev_attr_temp5_input.dev_attr.attr,
1217 &sensor_dev_attr_temp6_input.dev_attr.attr,
1218 &sensor_dev_attr_temp7_input.dev_attr.attr,
1219 &sensor_dev_attr_temp8_input.dev_attr.attr,
1220 &sensor_dev_attr_temp9_input.dev_attr.attr,
1221 &sensor_dev_attr_temp10_input.dev_attr.attr,
1222 &sensor_dev_attr_temp11_input.dev_attr.attr,
1223 &sensor_dev_attr_temp12_input.dev_attr.attr,
1224 &sensor_dev_attr_temp13_input.dev_attr.attr,
1225 &sensor_dev_attr_temp14_input.dev_attr.attr,
1226 &sensor_dev_attr_temp15_input.dev_attr.attr,
1227 &sensor_dev_attr_temp16_input.dev_attr.attr,
1228 &sensor_dev_attr_temp17_input.dev_attr.attr,
1229 &sensor_dev_attr_temp18_input.dev_attr.attr,
1230 &sensor_dev_attr_temp19_input.dev_attr.attr,
1231 &sensor_dev_attr_temp20_input.dev_attr.attr,
1232 &sensor_dev_attr_temp21_input.dev_attr.attr,
1233 &sensor_dev_attr_temp22_input.dev_attr.attr,
1234 &sensor_dev_attr_temp23_input.dev_attr.attr,
1235 &sensor_dev_attr_temp24_input.dev_attr.attr,
1236 &sensor_dev_attr_temp25_input.dev_attr.attr,
1237 &sensor_dev_attr_temp26_input.dev_attr.attr,
1238 &sensor_dev_attr_temp27_input.dev_attr.attr,
1239 &sensor_dev_attr_temp28_input.dev_attr.attr,
1240 &sensor_dev_attr_temp29_input.dev_attr.attr,
1241 &sensor_dev_attr_temp30_input.dev_attr.attr,
1242 &sensor_dev_attr_temp31_input.dev_attr.attr,
1243 &sensor_dev_attr_temp32_input.dev_attr.attr,
1244 &sensor_dev_attr_temp33_input.dev_attr.attr,
1245 &sensor_dev_attr_temp34_input.dev_attr.attr,
1246 &sensor_dev_attr_temp35_input.dev_attr.attr,
1247 &sensor_dev_attr_temp36_input.dev_attr.attr,
1248 &sensor_dev_attr_temp37_input.dev_attr.attr,
1249 &sensor_dev_attr_temp38_input.dev_attr.attr,
1250 &sensor_dev_attr_temp39_input.dev_attr.attr,
1251 &sensor_dev_attr_temp40_input.dev_attr.attr,
1255 static const struct attribute_group temperature_attributes_group =
1256 { .attrs = temperature_attributes };
1261 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1263 static int applesmc_dmi_match(const struct dmi_system_id *id)
1266 struct dmi_match_data* dmi_data = id->driver_data;
1267 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1268 applesmc_accelerometer = dmi_data->accelerometer;
1269 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1270 applesmc_accelerometer ? "with" : "without");
1271 applesmc_light = dmi_data->light;
1272 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1273 applesmc_light ? "with" : "without");
1275 applesmc_temperature_set = dmi_data->temperature_set;
1276 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1278 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1282 /* Create accelerometer ressources */
1283 static int applesmc_create_accelerometer(void)
1285 struct input_dev *idev;
1288 ret = sysfs_create_group(&pdev->dev.kobj,
1289 &accelerometer_attributes_group);
1293 applesmc_idev = input_allocate_polled_device();
1294 if (!applesmc_idev) {
1299 applesmc_idev->poll = applesmc_idev_poll;
1300 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1302 /* initial calibrate for the input device */
1303 applesmc_calibrate();
1305 /* initialize the input device */
1306 idev = applesmc_idev->input;
1307 idev->name = "applesmc";
1308 idev->id.bustype = BUS_HOST;
1309 idev->dev.parent = &pdev->dev;
1310 idev->evbit[0] = BIT_MASK(EV_ABS);
1311 input_set_abs_params(idev, ABS_X,
1312 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1313 input_set_abs_params(idev, ABS_Y,
1314 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1316 ret = input_register_polled_device(applesmc_idev);
1323 input_free_polled_device(applesmc_idev);
1326 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1329 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1333 /* Release all ressources used by the accelerometer */
1334 static void applesmc_release_accelerometer(void)
1336 input_unregister_polled_device(applesmc_idev);
1337 input_free_polled_device(applesmc_idev);
1338 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1341 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1342 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1343 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1344 /* MacBook2: accelerometer and temperature set 1 */
1345 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1346 /* MacBook: accelerometer and temperature set 2 */
1347 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1348 /* MacMini: temperature set 3 */
1349 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1350 /* MacPro: temperature set 4 */
1351 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1352 /* iMac: temperature set 5 */
1353 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1354 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1355 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1356 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1357 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1358 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1359 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1360 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1361 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1362 /* iMac 5: light sensor only, temperature set 10 */
1363 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1364 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1365 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
1366 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1367 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
1368 /* iMac 8: light sensor only, temperature set 13 */
1369 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
1370 /* iMac 6: light sensor only, temperature set 14 */
1371 { .accelerometer = 0, .light = 0, .temperature_set = 14 },
1372 /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
1373 { .accelerometer = 1, .light = 1, .temperature_set = 15 },
1374 /* MacPro3,1: temperature set 16 */
1375 { .accelerometer = 0, .light = 0, .temperature_set = 16 },
1376 /* iMac 9,1: light sensor only, temperature set 17 */
1377 { .accelerometer = 0, .light = 0, .temperature_set = 17 },
1378 /* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
1379 { .accelerometer = 1, .light = 1, .temperature_set = 18 },
1380 /* MacBook Pro 5,3: accelerometer, backlight and temperature set 19 */
1381 { .accelerometer = 1, .light = 1, .temperature_set = 19 },
1382 /* MacBook Pro 5,4: accelerometer, backlight and temperature set 20 */
1383 { .accelerometer = 1, .light = 1, .temperature_set = 20 },
1384 /* MacBook Pro 6,2: accelerometer, backlight and temperature set 21 */
1385 { .accelerometer = 1, .light = 1, .temperature_set = 21 },
1386 /* MacBook Pro 7,1: accelerometer, backlight and temperature set 22 */
1387 { .accelerometer = 1, .light = 1, .temperature_set = 22 },
1390 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1391 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1392 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1393 { applesmc_dmi_match, "Apple MacBook Air 2", {
1394 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1395 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
1396 &applesmc_dmi_data[15]},
1397 { applesmc_dmi_match, "Apple MacBook Air", {
1398 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1399 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1400 &applesmc_dmi_data[7]},
1401 { applesmc_dmi_match, "Apple MacBook Pro 7", {
1402 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1403 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro7") },
1404 &applesmc_dmi_data[22]},
1405 { applesmc_dmi_match, "Apple MacBook Pro 5,4", {
1406 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1407 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4") },
1408 &applesmc_dmi_data[20]},
1409 { applesmc_dmi_match, "Apple MacBook Pro 5,3", {
1410 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1411 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3") },
1412 &applesmc_dmi_data[19]},
1413 { applesmc_dmi_match, "Apple MacBook Pro 6", {
1414 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1415 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6") },
1416 &applesmc_dmi_data[21]},
1417 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1418 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1419 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1420 &applesmc_dmi_data[12]},
1421 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1422 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1423 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1424 &applesmc_dmi_data[8]},
1425 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1426 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1427 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1428 &applesmc_dmi_data[9]},
1429 { applesmc_dmi_match, "Apple MacBook Pro 2,2", {
1430 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
1431 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
1432 &applesmc_dmi_data[18]},
1433 { applesmc_dmi_match, "Apple MacBook Pro", {
1434 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1435 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1436 &applesmc_dmi_data[0]},
1437 { applesmc_dmi_match, "Apple MacBook (v2)", {
1438 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1439 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1440 &applesmc_dmi_data[1]},
1441 { applesmc_dmi_match, "Apple MacBook (v3)", {
1442 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1443 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1444 &applesmc_dmi_data[6]},
1445 { applesmc_dmi_match, "Apple MacBook 4", {
1446 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1447 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1448 &applesmc_dmi_data[6]},
1449 { applesmc_dmi_match, "Apple MacBook 5", {
1450 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1451 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1452 &applesmc_dmi_data[11]},
1453 { applesmc_dmi_match, "Apple MacBook", {
1454 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1455 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1456 &applesmc_dmi_data[2]},
1457 { applesmc_dmi_match, "Apple Macmini", {
1458 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1459 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1460 &applesmc_dmi_data[3]},
1461 { applesmc_dmi_match, "Apple MacPro2", {
1462 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1463 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1464 &applesmc_dmi_data[4]},
1465 { applesmc_dmi_match, "Apple MacPro3", {
1466 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1467 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") },
1468 &applesmc_dmi_data[16]},
1469 { applesmc_dmi_match, "Apple MacPro", {
1470 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1471 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1472 &applesmc_dmi_data[4]},
1473 { applesmc_dmi_match, "Apple iMac 9,1", {
1474 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
1475 DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
1476 &applesmc_dmi_data[17]},
1477 { applesmc_dmi_match, "Apple iMac 8", {
1478 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1479 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1480 &applesmc_dmi_data[13]},
1481 { applesmc_dmi_match, "Apple iMac 6", {
1482 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1483 DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
1484 &applesmc_dmi_data[14]},
1485 { applesmc_dmi_match, "Apple iMac 5", {
1486 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1487 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1488 &applesmc_dmi_data[10]},
1489 { applesmc_dmi_match, "Apple iMac", {
1490 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1491 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1492 &applesmc_dmi_data[5]},
1496 static int __init applesmc_init(void)
1502 if (!dmi_check_system(applesmc_whitelist)) {
1503 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1508 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1514 ret = platform_driver_register(&applesmc_driver);
1518 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1521 ret = PTR_ERR(pdev);
1525 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1529 /* Create key enumeration sysfs files */
1530 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1534 /* create fan files */
1535 count = applesmc_get_fan_count();
1537 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1539 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1543 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1544 " but at most 4 fans are supported"
1545 " by the driver.\n");
1548 while (fans_handled < count) {
1549 ret = sysfs_create_group(&pdev->dev.kobj,
1550 &fan_attribute_groups[fans_handled]);
1557 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1559 if (temperature_attributes[i] == NULL) {
1560 printk(KERN_ERR "applesmc: More temperature sensors "
1561 "in temperature_sensors_sets (at least %i)"
1562 "than available sysfs files in "
1563 "temperature_attributes (%i), please report "
1564 "this bug.\n", i, i-1);
1565 goto out_temperature;
1567 ret = sysfs_create_file(&pdev->dev.kobj,
1568 temperature_attributes[i]);
1570 goto out_temperature;
1573 if (applesmc_accelerometer) {
1574 ret = applesmc_create_accelerometer();
1576 goto out_temperature;
1579 if (applesmc_light) {
1580 /* Add light sensor file */
1581 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1583 goto out_accelerometer;
1585 /* Create the workqueue */
1586 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1587 if (!applesmc_led_wq) {
1589 goto out_light_sysfs;
1592 /* register as a led device */
1593 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1598 hwmon_dev = hwmon_device_register(&pdev->dev);
1599 if (IS_ERR(hwmon_dev)) {
1600 ret = PTR_ERR(hwmon_dev);
1601 goto out_light_ledclass;
1604 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1610 led_classdev_unregister(&applesmc_backlight);
1613 destroy_workqueue(applesmc_led_wq);
1616 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1618 if (applesmc_accelerometer)
1619 applesmc_release_accelerometer();
1621 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1623 while (fans_handled)
1624 sysfs_remove_group(&pdev->dev.kobj,
1625 &fan_attribute_groups[--fans_handled]);
1626 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1628 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1630 platform_device_unregister(pdev);
1632 platform_driver_unregister(&applesmc_driver);
1634 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1636 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1640 static void __exit applesmc_exit(void)
1642 hwmon_device_unregister(hwmon_dev);
1643 if (applesmc_light) {
1644 led_classdev_unregister(&applesmc_backlight);
1645 destroy_workqueue(applesmc_led_wq);
1646 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1648 if (applesmc_accelerometer)
1649 applesmc_release_accelerometer();
1650 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1651 while (fans_handled)
1652 sysfs_remove_group(&pdev->dev.kobj,
1653 &fan_attribute_groups[--fans_handled]);
1654 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1655 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1656 platform_device_unregister(pdev);
1657 platform_driver_unregister(&applesmc_driver);
1658 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1660 printk(KERN_INFO "applesmc: driver unloaded.\n");
1663 module_init(applesmc_init);
1664 module_exit(applesmc_exit);
1666 MODULE_AUTHOR("Nicolas Boichat");
1667 MODULE_DESCRIPTION("Apple SMC");
1668 MODULE_LICENSE("GPL v2");
1669 MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);