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",
147 /* List of keys used to read/write fan speeds */
148 static const char* fan_speed_keys
[] = {
156 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
157 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
159 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
160 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
161 #define APPLESMC_INPUT_FLAT 4
167 /* Structure to be passed to DMI_MATCH function */
168 struct dmi_match_data
{
169 /* Indicates whether this computer has an accelerometer. */
171 /* Indicates whether this computer has light sensors and keyboard backlight. */
173 /* Indicates which temperature sensors set to use. */
177 static const int debug
;
178 static struct platform_device
*pdev
;
181 static u8 backlight_state
[2];
183 static struct device
*hwmon_dev
;
184 static struct input_polled_dev
*applesmc_idev
;
186 /* Indicates whether this computer has an accelerometer. */
187 static unsigned int applesmc_accelerometer
;
189 /* Indicates whether this computer has light sensors and keyboard backlight. */
190 static unsigned int applesmc_light
;
192 /* Indicates which temperature sensors set to use. */
193 static unsigned int applesmc_temperature_set
;
195 static DEFINE_MUTEX(applesmc_lock
);
198 * Last index written to key_at_index sysfs file, and value to use for all other
199 * key_at_index_* sysfs files.
201 static unsigned int key_at_index
;
203 static struct workqueue_struct
*applesmc_led_wq
;
206 * __wait_status - Wait up to 32ms for the status port to get a certain value
207 * (masked with 0x0f), returning zero if the value is obtained. Callers must
208 * hold applesmc_lock.
210 static int __wait_status(u8 val
)
214 val
= val
& APPLESMC_STATUS_MASK
;
216 for (us
= APPLESMC_MIN_WAIT
; us
< APPLESMC_MAX_WAIT
; us
<<= 1) {
218 if ((inb(APPLESMC_CMD_PORT
) & APPLESMC_STATUS_MASK
) == val
) {
221 "Waited %d us for status %x\n",
222 2 * us
- APPLESMC_MIN_WAIT
, val
);
227 printk(KERN_WARNING
"applesmc: wait status failed: %x != %x\n",
228 val
, inb(APPLESMC_CMD_PORT
));
234 * special treatment of command port - on newer macbooks, it seems necessary
235 * to resend the command byte before polling the status again. Callers must
236 * hold applesmc_lock.
238 static int send_command(u8 cmd
)
241 for (us
= APPLESMC_MIN_WAIT
; us
< APPLESMC_MAX_WAIT
; us
<<= 1) {
242 outb(cmd
, APPLESMC_CMD_PORT
);
244 if ((inb(APPLESMC_CMD_PORT
) & APPLESMC_STATUS_MASK
) == 0x0c)
247 printk(KERN_WARNING
"applesmc: command failed: %x -> %x\n",
248 cmd
, inb(APPLESMC_CMD_PORT
));
253 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
254 * Returns zero on success or a negative error on failure. Callers must
255 * hold applesmc_lock.
257 static int applesmc_read_key(const char* key
, u8
* buffer
, u8 len
)
261 if (len
> APPLESMC_MAX_DATA_LENGTH
) {
262 printk(KERN_ERR
"applesmc_read_key: cannot read more than "
263 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH
);
267 if (send_command(APPLESMC_READ_CMD
))
270 for (i
= 0; i
< 4; i
++) {
271 outb(key
[i
], APPLESMC_DATA_PORT
);
272 if (__wait_status(0x04))
276 printk(KERN_DEBUG
"<%s", key
);
278 outb(len
, APPLESMC_DATA_PORT
);
280 printk(KERN_DEBUG
">%x", len
);
282 for (i
= 0; i
< len
; i
++) {
283 if (__wait_status(0x05))
285 buffer
[i
] = inb(APPLESMC_DATA_PORT
);
287 printk(KERN_DEBUG
"<%x", buffer
[i
]);
290 printk(KERN_DEBUG
"\n");
296 * applesmc_write_key - writes len bytes from buffer to a given key.
297 * Returns zero on success or a negative error on failure. Callers must
298 * hold applesmc_lock.
300 static int applesmc_write_key(const char* key
, u8
* buffer
, u8 len
)
304 if (len
> APPLESMC_MAX_DATA_LENGTH
) {
305 printk(KERN_ERR
"applesmc_write_key: cannot write more than "
306 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH
);
310 if (send_command(APPLESMC_WRITE_CMD
))
313 for (i
= 0; i
< 4; i
++) {
314 outb(key
[i
], APPLESMC_DATA_PORT
);
315 if (__wait_status(0x04))
319 outb(len
, APPLESMC_DATA_PORT
);
321 for (i
= 0; i
< len
; i
++) {
322 if (__wait_status(0x04))
324 outb(buffer
[i
], APPLESMC_DATA_PORT
);
331 * applesmc_get_key_at_index - get key at index, and put the result in key
332 * (char[6]). Returns zero on success or a negative error on failure. Callers
333 * must hold applesmc_lock.
335 static int applesmc_get_key_at_index(int index
, char* key
)
339 readkey
[0] = index
>> 24;
340 readkey
[1] = index
>> 16;
341 readkey
[2] = index
>> 8;
344 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD
))
347 for (i
= 0; i
< 4; i
++) {
348 outb(readkey
[i
], APPLESMC_DATA_PORT
);
349 if (__wait_status(0x04))
353 outb(4, APPLESMC_DATA_PORT
);
355 for (i
= 0; i
< 4; i
++) {
356 if (__wait_status(0x05))
358 key
[i
] = inb(APPLESMC_DATA_PORT
);
366 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
367 * Returns zero on success or a negative error on failure. Callers must
368 * hold applesmc_lock.
370 static int applesmc_get_key_type(char* key
, char* type
)
374 if (send_command(APPLESMC_GET_KEY_TYPE_CMD
))
377 for (i
= 0; i
< 4; i
++) {
378 outb(key
[i
], APPLESMC_DATA_PORT
);
379 if (__wait_status(0x04))
383 outb(6, APPLESMC_DATA_PORT
);
385 for (i
= 0; i
< 6; i
++) {
386 if (__wait_status(0x05))
388 type
[i
] = inb(APPLESMC_DATA_PORT
);
396 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
397 * hold applesmc_lock.
399 static int applesmc_read_motion_sensor(int index
, s16
* value
)
406 ret
= applesmc_read_key(MOTION_SENSOR_X_KEY
, buffer
, 2);
409 ret
= applesmc_read_key(MOTION_SENSOR_Y_KEY
, buffer
, 2);
412 ret
= applesmc_read_key(MOTION_SENSOR_Z_KEY
, buffer
, 2);
418 *value
= ((s16
)buffer
[0] << 8) | buffer
[1];
424 * applesmc_device_init - initialize the accelerometer. Returns zero on success
425 * and negative error code on failure. Can sleep.
427 static int applesmc_device_init(void)
429 int total
, ret
= -ENXIO
;
432 if (!applesmc_accelerometer
)
435 mutex_lock(&applesmc_lock
);
437 for (total
= INIT_TIMEOUT_MSECS
; total
> 0; total
-= INIT_WAIT_MSECS
) {
439 printk(KERN_DEBUG
"applesmc try %d\n", total
);
440 if (!applesmc_read_key(MOTION_SENSOR_KEY
, buffer
, 2) &&
441 (buffer
[0] != 0x00 || buffer
[1] != 0x00)) {
442 if (total
== INIT_TIMEOUT_MSECS
) {
443 printk(KERN_DEBUG
"applesmc: device has"
444 " already been initialized"
445 " (0x%02x, 0x%02x).\n",
446 buffer
[0], buffer
[1]);
448 printk(KERN_DEBUG
"applesmc: device"
449 " successfully initialized"
450 " (0x%02x, 0x%02x).\n",
451 buffer
[0], buffer
[1]);
458 applesmc_write_key(MOTION_SENSOR_KEY
, buffer
, 2);
459 msleep(INIT_WAIT_MSECS
);
462 printk(KERN_WARNING
"applesmc: failed to init the device\n");
465 mutex_unlock(&applesmc_lock
);
470 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
473 static int applesmc_get_fan_count(void)
478 mutex_lock(&applesmc_lock
);
480 ret
= applesmc_read_key(FANS_COUNT
, buffer
, 1);
482 mutex_unlock(&applesmc_lock
);
489 /* Device model stuff */
490 static int applesmc_probe(struct platform_device
*dev
)
494 ret
= applesmc_device_init();
498 printk(KERN_INFO
"applesmc: device successfully initialized.\n");
502 /* Synchronize device with memorized backlight state */
503 static int applesmc_pm_resume(struct device
*dev
)
505 mutex_lock(&applesmc_lock
);
507 applesmc_write_key(BACKLIGHT_KEY
, backlight_state
, 2);
508 mutex_unlock(&applesmc_lock
);
512 /* Reinitialize device on resume from hibernation */
513 static int applesmc_pm_restore(struct device
*dev
)
515 int ret
= applesmc_device_init();
518 return applesmc_pm_resume(dev
);
521 static struct dev_pm_ops applesmc_pm_ops
= {
522 .resume
= applesmc_pm_resume
,
523 .restore
= applesmc_pm_restore
,
526 static struct platform_driver applesmc_driver
= {
527 .probe
= applesmc_probe
,
530 .owner
= THIS_MODULE
,
531 .pm
= &applesmc_pm_ops
,
536 * applesmc_calibrate - Set our "resting" values. Callers must
537 * hold applesmc_lock.
539 static void applesmc_calibrate(void)
541 applesmc_read_motion_sensor(SENSOR_X
, &rest_x
);
542 applesmc_read_motion_sensor(SENSOR_Y
, &rest_y
);
546 static void applesmc_idev_poll(struct input_polled_dev
*dev
)
548 struct input_dev
*idev
= dev
->input
;
551 mutex_lock(&applesmc_lock
);
553 if (applesmc_read_motion_sensor(SENSOR_X
, &x
))
555 if (applesmc_read_motion_sensor(SENSOR_Y
, &y
))
559 input_report_abs(idev
, ABS_X
, x
- rest_x
);
560 input_report_abs(idev
, ABS_Y
, y
- rest_y
);
564 mutex_unlock(&applesmc_lock
);
569 static ssize_t
applesmc_name_show(struct device
*dev
,
570 struct device_attribute
*attr
, char *buf
)
572 return snprintf(buf
, PAGE_SIZE
, "applesmc\n");
575 static ssize_t
applesmc_position_show(struct device
*dev
,
576 struct device_attribute
*attr
, char *buf
)
581 mutex_lock(&applesmc_lock
);
583 ret
= applesmc_read_motion_sensor(SENSOR_X
, &x
);
586 ret
= applesmc_read_motion_sensor(SENSOR_Y
, &y
);
589 ret
= applesmc_read_motion_sensor(SENSOR_Z
, &z
);
594 mutex_unlock(&applesmc_lock
);
598 return snprintf(buf
, PAGE_SIZE
, "(%d,%d,%d)\n", x
, y
, z
);
601 static ssize_t
applesmc_light_show(struct device
*dev
,
602 struct device_attribute
*attr
, char *sysfsbuf
)
604 static int data_length
;
606 u8 left
= 0, right
= 0;
607 u8 buffer
[10], query
[6];
609 mutex_lock(&applesmc_lock
);
612 ret
= applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY
, query
);
615 data_length
= clamp_val(query
[0], 0, 10);
616 printk(KERN_INFO
"applesmc: light sensor data length set to "
617 "%d\n", data_length
);
620 ret
= applesmc_read_key(LIGHT_SENSOR_LEFT_KEY
, buffer
, data_length
);
621 /* newer macbooks report a single 10-bit bigendian value */
622 if (data_length
== 10) {
623 left
= be16_to_cpu(*(__be16
*)(buffer
+ 6)) >> 2;
629 ret
= applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY
, buffer
, data_length
);
633 mutex_unlock(&applesmc_lock
);
637 return snprintf(sysfsbuf
, PAGE_SIZE
, "(%d,%d)\n", left
, right
);
640 /* Displays degree Celsius * 1000 */
641 static ssize_t
applesmc_show_temperature(struct device
*dev
,
642 struct device_attribute
*devattr
, char *sysfsbuf
)
647 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
649 temperature_sensors_sets
[applesmc_temperature_set
][attr
->index
];
651 mutex_lock(&applesmc_lock
);
653 ret
= applesmc_read_key(key
, buffer
, 2);
654 temp
= buffer
[0]*1000;
655 temp
+= (buffer
[1] >> 6) * 250;
657 mutex_unlock(&applesmc_lock
);
662 return snprintf(sysfsbuf
, PAGE_SIZE
, "%u\n", temp
);
665 static ssize_t
applesmc_show_fan_speed(struct device
*dev
,
666 struct device_attribute
*attr
, char *sysfsbuf
)
669 unsigned int speed
= 0;
672 struct sensor_device_attribute_2
*sensor_attr
=
673 to_sensor_dev_attr_2(attr
);
675 newkey
[0] = fan_speed_keys
[sensor_attr
->nr
][0];
676 newkey
[1] = '0' + sensor_attr
->index
;
677 newkey
[2] = fan_speed_keys
[sensor_attr
->nr
][2];
678 newkey
[3] = fan_speed_keys
[sensor_attr
->nr
][3];
681 mutex_lock(&applesmc_lock
);
683 ret
= applesmc_read_key(newkey
, buffer
, 2);
684 speed
= ((buffer
[0] << 8 | buffer
[1]) >> 2);
686 mutex_unlock(&applesmc_lock
);
690 return snprintf(sysfsbuf
, PAGE_SIZE
, "%u\n", speed
);
693 static ssize_t
applesmc_store_fan_speed(struct device
*dev
,
694 struct device_attribute
*attr
,
695 const char *sysfsbuf
, size_t count
)
701 struct sensor_device_attribute_2
*sensor_attr
=
702 to_sensor_dev_attr_2(attr
);
704 speed
= simple_strtoul(sysfsbuf
, NULL
, 10);
706 if (speed
> 0x4000) /* Bigger than a 14-bit value */
709 newkey
[0] = fan_speed_keys
[sensor_attr
->nr
][0];
710 newkey
[1] = '0' + sensor_attr
->index
;
711 newkey
[2] = fan_speed_keys
[sensor_attr
->nr
][2];
712 newkey
[3] = fan_speed_keys
[sensor_attr
->nr
][3];
715 mutex_lock(&applesmc_lock
);
717 buffer
[0] = (speed
>> 6) & 0xff;
718 buffer
[1] = (speed
<< 2) & 0xff;
719 ret
= applesmc_write_key(newkey
, buffer
, 2);
721 mutex_unlock(&applesmc_lock
);
728 static ssize_t
applesmc_show_fan_manual(struct device
*dev
,
729 struct device_attribute
*devattr
, char *sysfsbuf
)
734 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
736 mutex_lock(&applesmc_lock
);
738 ret
= applesmc_read_key(FANS_MANUAL
, buffer
, 2);
739 manual
= ((buffer
[0] << 8 | buffer
[1]) >> attr
->index
) & 0x01;
741 mutex_unlock(&applesmc_lock
);
745 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", manual
);
748 static ssize_t
applesmc_store_fan_manual(struct device
*dev
,
749 struct device_attribute
*devattr
,
750 const char *sysfsbuf
, size_t count
)
756 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
758 input
= simple_strtoul(sysfsbuf
, NULL
, 10);
760 mutex_lock(&applesmc_lock
);
762 ret
= applesmc_read_key(FANS_MANUAL
, buffer
, 2);
763 val
= (buffer
[0] << 8 | buffer
[1]);
768 val
= val
| (0x01 << attr
->index
);
770 val
= val
& ~(0x01 << attr
->index
);
772 buffer
[0] = (val
>> 8) & 0xFF;
773 buffer
[1] = val
& 0xFF;
775 ret
= applesmc_write_key(FANS_MANUAL
, buffer
, 2);
778 mutex_unlock(&applesmc_lock
);
785 static ssize_t
applesmc_show_fan_position(struct device
*dev
,
786 struct device_attribute
*attr
, char *sysfsbuf
)
791 struct sensor_device_attribute_2
*sensor_attr
=
792 to_sensor_dev_attr_2(attr
);
794 newkey
[0] = FAN_POSITION
[0];
795 newkey
[1] = '0' + sensor_attr
->index
;
796 newkey
[2] = FAN_POSITION
[2];
797 newkey
[3] = FAN_POSITION
[3];
800 mutex_lock(&applesmc_lock
);
802 ret
= applesmc_read_key(newkey
, buffer
, 16);
805 mutex_unlock(&applesmc_lock
);
809 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", buffer
+4);
812 static ssize_t
applesmc_calibrate_show(struct device
*dev
,
813 struct device_attribute
*attr
, char *sysfsbuf
)
815 return snprintf(sysfsbuf
, PAGE_SIZE
, "(%d,%d)\n", rest_x
, rest_y
);
818 static ssize_t
applesmc_calibrate_store(struct device
*dev
,
819 struct device_attribute
*attr
, const char *sysfsbuf
, size_t count
)
821 mutex_lock(&applesmc_lock
);
822 applesmc_calibrate();
823 mutex_unlock(&applesmc_lock
);
828 static void applesmc_backlight_set(struct work_struct
*work
)
830 mutex_lock(&applesmc_lock
);
831 applesmc_write_key(BACKLIGHT_KEY
, backlight_state
, 2);
832 mutex_unlock(&applesmc_lock
);
834 static DECLARE_WORK(backlight_work
, &applesmc_backlight_set
);
836 static void applesmc_brightness_set(struct led_classdev
*led_cdev
,
837 enum led_brightness value
)
841 backlight_state
[0] = value
;
842 ret
= queue_work(applesmc_led_wq
, &backlight_work
);
845 printk(KERN_DEBUG
"applesmc: work was already on the queue.\n");
848 static ssize_t
applesmc_key_count_show(struct device
*dev
,
849 struct device_attribute
*attr
, char *sysfsbuf
)
855 mutex_lock(&applesmc_lock
);
857 ret
= applesmc_read_key(KEY_COUNT_KEY
, buffer
, 4);
858 count
= ((u32
)buffer
[0]<<24) + ((u32
)buffer
[1]<<16) +
859 ((u32
)buffer
[2]<<8) + buffer
[3];
861 mutex_unlock(&applesmc_lock
);
865 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", count
);
868 static ssize_t
applesmc_key_at_index_read_show(struct device
*dev
,
869 struct device_attribute
*attr
, char *sysfsbuf
)
875 mutex_lock(&applesmc_lock
);
877 ret
= applesmc_get_key_at_index(key_at_index
, key
);
879 if (ret
|| !key
[0]) {
880 mutex_unlock(&applesmc_lock
);
885 ret
= applesmc_get_key_type(key
, info
);
888 mutex_unlock(&applesmc_lock
);
894 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
895 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
897 ret
= applesmc_read_key(key
, sysfsbuf
, info
[0]);
899 mutex_unlock(&applesmc_lock
);
908 static ssize_t
applesmc_key_at_index_data_length_show(struct device
*dev
,
909 struct device_attribute
*attr
, char *sysfsbuf
)
915 mutex_lock(&applesmc_lock
);
917 ret
= applesmc_get_key_at_index(key_at_index
, key
);
919 if (ret
|| !key
[0]) {
920 mutex_unlock(&applesmc_lock
);
925 ret
= applesmc_get_key_type(key
, info
);
927 mutex_unlock(&applesmc_lock
);
930 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", info
[0]);
935 static ssize_t
applesmc_key_at_index_type_show(struct device
*dev
,
936 struct device_attribute
*attr
, char *sysfsbuf
)
942 mutex_lock(&applesmc_lock
);
944 ret
= applesmc_get_key_at_index(key_at_index
, key
);
946 if (ret
|| !key
[0]) {
947 mutex_unlock(&applesmc_lock
);
952 ret
= applesmc_get_key_type(key
, info
);
954 mutex_unlock(&applesmc_lock
);
957 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", info
+1);
962 static ssize_t
applesmc_key_at_index_name_show(struct device
*dev
,
963 struct device_attribute
*attr
, char *sysfsbuf
)
968 mutex_lock(&applesmc_lock
);
970 ret
= applesmc_get_key_at_index(key_at_index
, key
);
972 mutex_unlock(&applesmc_lock
);
975 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", key
);
980 static ssize_t
applesmc_key_at_index_show(struct device
*dev
,
981 struct device_attribute
*attr
, char *sysfsbuf
)
983 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", key_at_index
);
986 static ssize_t
applesmc_key_at_index_store(struct device
*dev
,
987 struct device_attribute
*attr
, const char *sysfsbuf
, size_t count
)
989 mutex_lock(&applesmc_lock
);
991 key_at_index
= simple_strtoul(sysfsbuf
, NULL
, 10);
993 mutex_unlock(&applesmc_lock
);
998 static struct led_classdev applesmc_backlight
= {
999 .name
= "smc::kbd_backlight",
1000 .default_trigger
= "nand-disk",
1001 .brightness_set
= applesmc_brightness_set
,
1004 static DEVICE_ATTR(name
, 0444, applesmc_name_show
, NULL
);
1006 static DEVICE_ATTR(position
, 0444, applesmc_position_show
, NULL
);
1007 static DEVICE_ATTR(calibrate
, 0644,
1008 applesmc_calibrate_show
, applesmc_calibrate_store
);
1010 static struct attribute
*accelerometer_attributes
[] = {
1011 &dev_attr_position
.attr
,
1012 &dev_attr_calibrate
.attr
,
1016 static const struct attribute_group accelerometer_attributes_group
=
1017 { .attrs
= accelerometer_attributes
};
1019 static DEVICE_ATTR(light
, 0444, applesmc_light_show
, NULL
);
1021 static DEVICE_ATTR(key_count
, 0444, applesmc_key_count_show
, NULL
);
1022 static DEVICE_ATTR(key_at_index
, 0644,
1023 applesmc_key_at_index_show
, applesmc_key_at_index_store
);
1024 static DEVICE_ATTR(key_at_index_name
, 0444,
1025 applesmc_key_at_index_name_show
, NULL
);
1026 static DEVICE_ATTR(key_at_index_type
, 0444,
1027 applesmc_key_at_index_type_show
, NULL
);
1028 static DEVICE_ATTR(key_at_index_data_length
, 0444,
1029 applesmc_key_at_index_data_length_show
, NULL
);
1030 static DEVICE_ATTR(key_at_index_data
, 0444,
1031 applesmc_key_at_index_read_show
, NULL
);
1033 static struct attribute
*key_enumeration_attributes
[] = {
1034 &dev_attr_key_count
.attr
,
1035 &dev_attr_key_at_index
.attr
,
1036 &dev_attr_key_at_index_name
.attr
,
1037 &dev_attr_key_at_index_type
.attr
,
1038 &dev_attr_key_at_index_data_length
.attr
,
1039 &dev_attr_key_at_index_data
.attr
,
1043 static const struct attribute_group key_enumeration_group
=
1044 { .attrs
= key_enumeration_attributes
};
1047 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1048 * - show actual speed
1049 * - show/store minimum speed
1050 * - show maximum speed
1052 * - show/store target speed
1053 * - show/store manual mode
1055 #define sysfs_fan_speeds_offset(offset) \
1056 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1057 applesmc_show_fan_speed, NULL, 0, offset-1); \
1059 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1060 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1062 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1063 applesmc_show_fan_speed, NULL, 2, offset-1); \
1065 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1066 applesmc_show_fan_speed, NULL, 3, offset-1); \
1068 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1069 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1071 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1072 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1074 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1075 applesmc_show_fan_position, NULL, offset-1); \
1077 static struct attribute *fan##offset##_attributes[] = { \
1078 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1079 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1080 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1081 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1082 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1083 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1084 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1089 * Create the needed functions for each fan using the macro defined above
1090 * (4 fans are supported)
1092 sysfs_fan_speeds_offset(1);
1093 sysfs_fan_speeds_offset(2);
1094 sysfs_fan_speeds_offset(3);
1095 sysfs_fan_speeds_offset(4);
1097 static const struct attribute_group fan_attribute_groups
[] = {
1098 { .attrs
= fan1_attributes
},
1099 { .attrs
= fan2_attributes
},
1100 { .attrs
= fan3_attributes
},
1101 { .attrs
= fan4_attributes
},
1105 * Temperature sensors sysfs entries.
1107 static SENSOR_DEVICE_ATTR(temp1_input
, S_IRUGO
,
1108 applesmc_show_temperature
, NULL
, 0);
1109 static SENSOR_DEVICE_ATTR(temp2_input
, S_IRUGO
,
1110 applesmc_show_temperature
, NULL
, 1);
1111 static SENSOR_DEVICE_ATTR(temp3_input
, S_IRUGO
,
1112 applesmc_show_temperature
, NULL
, 2);
1113 static SENSOR_DEVICE_ATTR(temp4_input
, S_IRUGO
,
1114 applesmc_show_temperature
, NULL
, 3);
1115 static SENSOR_DEVICE_ATTR(temp5_input
, S_IRUGO
,
1116 applesmc_show_temperature
, NULL
, 4);
1117 static SENSOR_DEVICE_ATTR(temp6_input
, S_IRUGO
,
1118 applesmc_show_temperature
, NULL
, 5);
1119 static SENSOR_DEVICE_ATTR(temp7_input
, S_IRUGO
,
1120 applesmc_show_temperature
, NULL
, 6);
1121 static SENSOR_DEVICE_ATTR(temp8_input
, S_IRUGO
,
1122 applesmc_show_temperature
, NULL
, 7);
1123 static SENSOR_DEVICE_ATTR(temp9_input
, S_IRUGO
,
1124 applesmc_show_temperature
, NULL
, 8);
1125 static SENSOR_DEVICE_ATTR(temp10_input
, S_IRUGO
,
1126 applesmc_show_temperature
, NULL
, 9);
1127 static SENSOR_DEVICE_ATTR(temp11_input
, S_IRUGO
,
1128 applesmc_show_temperature
, NULL
, 10);
1129 static SENSOR_DEVICE_ATTR(temp12_input
, S_IRUGO
,
1130 applesmc_show_temperature
, NULL
, 11);
1131 static SENSOR_DEVICE_ATTR(temp13_input
, S_IRUGO
,
1132 applesmc_show_temperature
, NULL
, 12);
1133 static SENSOR_DEVICE_ATTR(temp14_input
, S_IRUGO
,
1134 applesmc_show_temperature
, NULL
, 13);
1135 static SENSOR_DEVICE_ATTR(temp15_input
, S_IRUGO
,
1136 applesmc_show_temperature
, NULL
, 14);
1137 static SENSOR_DEVICE_ATTR(temp16_input
, S_IRUGO
,
1138 applesmc_show_temperature
, NULL
, 15);
1139 static SENSOR_DEVICE_ATTR(temp17_input
, S_IRUGO
,
1140 applesmc_show_temperature
, NULL
, 16);
1141 static SENSOR_DEVICE_ATTR(temp18_input
, S_IRUGO
,
1142 applesmc_show_temperature
, NULL
, 17);
1143 static SENSOR_DEVICE_ATTR(temp19_input
, S_IRUGO
,
1144 applesmc_show_temperature
, NULL
, 18);
1145 static SENSOR_DEVICE_ATTR(temp20_input
, S_IRUGO
,
1146 applesmc_show_temperature
, NULL
, 19);
1147 static SENSOR_DEVICE_ATTR(temp21_input
, S_IRUGO
,
1148 applesmc_show_temperature
, NULL
, 20);
1149 static SENSOR_DEVICE_ATTR(temp22_input
, S_IRUGO
,
1150 applesmc_show_temperature
, NULL
, 21);
1151 static SENSOR_DEVICE_ATTR(temp23_input
, S_IRUGO
,
1152 applesmc_show_temperature
, NULL
, 22);
1153 static SENSOR_DEVICE_ATTR(temp24_input
, S_IRUGO
,
1154 applesmc_show_temperature
, NULL
, 23);
1155 static SENSOR_DEVICE_ATTR(temp25_input
, S_IRUGO
,
1156 applesmc_show_temperature
, NULL
, 24);
1157 static SENSOR_DEVICE_ATTR(temp26_input
, S_IRUGO
,
1158 applesmc_show_temperature
, NULL
, 25);
1159 static SENSOR_DEVICE_ATTR(temp27_input
, S_IRUGO
,
1160 applesmc_show_temperature
, NULL
, 26);
1161 static SENSOR_DEVICE_ATTR(temp28_input
, S_IRUGO
,
1162 applesmc_show_temperature
, NULL
, 27);
1163 static SENSOR_DEVICE_ATTR(temp29_input
, S_IRUGO
,
1164 applesmc_show_temperature
, NULL
, 28);
1165 static SENSOR_DEVICE_ATTR(temp30_input
, S_IRUGO
,
1166 applesmc_show_temperature
, NULL
, 29);
1167 static SENSOR_DEVICE_ATTR(temp31_input
, S_IRUGO
,
1168 applesmc_show_temperature
, NULL
, 30);
1169 static SENSOR_DEVICE_ATTR(temp32_input
, S_IRUGO
,
1170 applesmc_show_temperature
, NULL
, 31);
1171 static SENSOR_DEVICE_ATTR(temp33_input
, S_IRUGO
,
1172 applesmc_show_temperature
, NULL
, 32);
1173 static SENSOR_DEVICE_ATTR(temp34_input
, S_IRUGO
,
1174 applesmc_show_temperature
, NULL
, 33);
1175 static SENSOR_DEVICE_ATTR(temp35_input
, S_IRUGO
,
1176 applesmc_show_temperature
, NULL
, 34);
1177 static SENSOR_DEVICE_ATTR(temp36_input
, S_IRUGO
,
1178 applesmc_show_temperature
, NULL
, 35);
1179 static SENSOR_DEVICE_ATTR(temp37_input
, S_IRUGO
,
1180 applesmc_show_temperature
, NULL
, 36);
1181 static SENSOR_DEVICE_ATTR(temp38_input
, S_IRUGO
,
1182 applesmc_show_temperature
, NULL
, 37);
1183 static SENSOR_DEVICE_ATTR(temp39_input
, S_IRUGO
,
1184 applesmc_show_temperature
, NULL
, 38);
1185 static SENSOR_DEVICE_ATTR(temp40_input
, S_IRUGO
,
1186 applesmc_show_temperature
, NULL
, 39);
1188 static struct attribute
*temperature_attributes
[] = {
1189 &sensor_dev_attr_temp1_input
.dev_attr
.attr
,
1190 &sensor_dev_attr_temp2_input
.dev_attr
.attr
,
1191 &sensor_dev_attr_temp3_input
.dev_attr
.attr
,
1192 &sensor_dev_attr_temp4_input
.dev_attr
.attr
,
1193 &sensor_dev_attr_temp5_input
.dev_attr
.attr
,
1194 &sensor_dev_attr_temp6_input
.dev_attr
.attr
,
1195 &sensor_dev_attr_temp7_input
.dev_attr
.attr
,
1196 &sensor_dev_attr_temp8_input
.dev_attr
.attr
,
1197 &sensor_dev_attr_temp9_input
.dev_attr
.attr
,
1198 &sensor_dev_attr_temp10_input
.dev_attr
.attr
,
1199 &sensor_dev_attr_temp11_input
.dev_attr
.attr
,
1200 &sensor_dev_attr_temp12_input
.dev_attr
.attr
,
1201 &sensor_dev_attr_temp13_input
.dev_attr
.attr
,
1202 &sensor_dev_attr_temp14_input
.dev_attr
.attr
,
1203 &sensor_dev_attr_temp15_input
.dev_attr
.attr
,
1204 &sensor_dev_attr_temp16_input
.dev_attr
.attr
,
1205 &sensor_dev_attr_temp17_input
.dev_attr
.attr
,
1206 &sensor_dev_attr_temp18_input
.dev_attr
.attr
,
1207 &sensor_dev_attr_temp19_input
.dev_attr
.attr
,
1208 &sensor_dev_attr_temp20_input
.dev_attr
.attr
,
1209 &sensor_dev_attr_temp21_input
.dev_attr
.attr
,
1210 &sensor_dev_attr_temp22_input
.dev_attr
.attr
,
1211 &sensor_dev_attr_temp23_input
.dev_attr
.attr
,
1212 &sensor_dev_attr_temp24_input
.dev_attr
.attr
,
1213 &sensor_dev_attr_temp25_input
.dev_attr
.attr
,
1214 &sensor_dev_attr_temp26_input
.dev_attr
.attr
,
1215 &sensor_dev_attr_temp27_input
.dev_attr
.attr
,
1216 &sensor_dev_attr_temp28_input
.dev_attr
.attr
,
1217 &sensor_dev_attr_temp29_input
.dev_attr
.attr
,
1218 &sensor_dev_attr_temp30_input
.dev_attr
.attr
,
1219 &sensor_dev_attr_temp31_input
.dev_attr
.attr
,
1220 &sensor_dev_attr_temp32_input
.dev_attr
.attr
,
1221 &sensor_dev_attr_temp33_input
.dev_attr
.attr
,
1222 &sensor_dev_attr_temp34_input
.dev_attr
.attr
,
1223 &sensor_dev_attr_temp35_input
.dev_attr
.attr
,
1224 &sensor_dev_attr_temp36_input
.dev_attr
.attr
,
1225 &sensor_dev_attr_temp37_input
.dev_attr
.attr
,
1226 &sensor_dev_attr_temp38_input
.dev_attr
.attr
,
1227 &sensor_dev_attr_temp39_input
.dev_attr
.attr
,
1228 &sensor_dev_attr_temp40_input
.dev_attr
.attr
,
1232 static const struct attribute_group temperature_attributes_group
=
1233 { .attrs
= temperature_attributes
};
1238 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1240 static int applesmc_dmi_match(const struct dmi_system_id
*id
)
1243 struct dmi_match_data
* dmi_data
= id
->driver_data
;
1244 printk(KERN_INFO
"applesmc: %s detected:\n", id
->ident
);
1245 applesmc_accelerometer
= dmi_data
->accelerometer
;
1246 printk(KERN_INFO
"applesmc: - Model %s accelerometer\n",
1247 applesmc_accelerometer
? "with" : "without");
1248 applesmc_light
= dmi_data
->light
;
1249 printk(KERN_INFO
"applesmc: - Model %s light sensors and backlight\n",
1250 applesmc_light
? "with" : "without");
1252 applesmc_temperature_set
= dmi_data
->temperature_set
;
1253 while (temperature_sensors_sets
[applesmc_temperature_set
][i
] != NULL
)
1255 printk(KERN_INFO
"applesmc: - Model with %d temperature sensors\n", i
);
1259 /* Create accelerometer ressources */
1260 static int applesmc_create_accelerometer(void)
1262 struct input_dev
*idev
;
1265 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1266 &accelerometer_attributes_group
);
1270 applesmc_idev
= input_allocate_polled_device();
1271 if (!applesmc_idev
) {
1276 applesmc_idev
->poll
= applesmc_idev_poll
;
1277 applesmc_idev
->poll_interval
= APPLESMC_POLL_INTERVAL
;
1279 /* initial calibrate for the input device */
1280 applesmc_calibrate();
1282 /* initialize the input device */
1283 idev
= applesmc_idev
->input
;
1284 idev
->name
= "applesmc";
1285 idev
->id
.bustype
= BUS_HOST
;
1286 idev
->dev
.parent
= &pdev
->dev
;
1287 idev
->evbit
[0] = BIT_MASK(EV_ABS
);
1288 input_set_abs_params(idev
, ABS_X
,
1289 -256, 256, APPLESMC_INPUT_FUZZ
, APPLESMC_INPUT_FLAT
);
1290 input_set_abs_params(idev
, ABS_Y
,
1291 -256, 256, APPLESMC_INPUT_FUZZ
, APPLESMC_INPUT_FLAT
);
1293 ret
= input_register_polled_device(applesmc_idev
);
1300 input_free_polled_device(applesmc_idev
);
1303 sysfs_remove_group(&pdev
->dev
.kobj
, &accelerometer_attributes_group
);
1306 printk(KERN_WARNING
"applesmc: driver init failed (ret=%d)!\n", ret
);
1310 /* Release all ressources used by the accelerometer */
1311 static void applesmc_release_accelerometer(void)
1313 input_unregister_polled_device(applesmc_idev
);
1314 input_free_polled_device(applesmc_idev
);
1315 sysfs_remove_group(&pdev
->dev
.kobj
, &accelerometer_attributes_group
);
1318 static __initdata
struct dmi_match_data applesmc_dmi_data
[] = {
1319 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1320 { .accelerometer
= 1, .light
= 1, .temperature_set
= 0 },
1321 /* MacBook2: accelerometer and temperature set 1 */
1322 { .accelerometer
= 1, .light
= 0, .temperature_set
= 1 },
1323 /* MacBook: accelerometer and temperature set 2 */
1324 { .accelerometer
= 1, .light
= 0, .temperature_set
= 2 },
1325 /* MacMini: temperature set 3 */
1326 { .accelerometer
= 0, .light
= 0, .temperature_set
= 3 },
1327 /* MacPro: temperature set 4 */
1328 { .accelerometer
= 0, .light
= 0, .temperature_set
= 4 },
1329 /* iMac: temperature set 5 */
1330 { .accelerometer
= 0, .light
= 0, .temperature_set
= 5 },
1331 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1332 { .accelerometer
= 1, .light
= 0, .temperature_set
= 6 },
1333 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1334 { .accelerometer
= 1, .light
= 1, .temperature_set
= 7 },
1335 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1336 { .accelerometer
= 1, .light
= 1, .temperature_set
= 8 },
1337 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1338 { .accelerometer
= 1, .light
= 1, .temperature_set
= 9 },
1339 /* iMac 5: light sensor only, temperature set 10 */
1340 { .accelerometer
= 0, .light
= 0, .temperature_set
= 10 },
1341 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1342 { .accelerometer
= 1, .light
= 1, .temperature_set
= 11 },
1343 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1344 { .accelerometer
= 1, .light
= 1, .temperature_set
= 12 },
1345 /* iMac 8: light sensor only, temperature set 13 */
1346 { .accelerometer
= 0, .light
= 0, .temperature_set
= 13 },
1347 /* iMac 6: light sensor only, temperature set 14 */
1348 { .accelerometer
= 0, .light
= 0, .temperature_set
= 14 },
1349 /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
1350 { .accelerometer
= 1, .light
= 1, .temperature_set
= 15 },
1351 /* MacPro3,1: temperature set 16 */
1352 { .accelerometer
= 0, .light
= 0, .temperature_set
= 16 },
1355 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1356 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1357 static __initdata
struct dmi_system_id applesmc_whitelist
[] = {
1358 { applesmc_dmi_match
, "Apple MacBook Air 2", {
1359 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1360 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookAir2") },
1361 &applesmc_dmi_data
[15]},
1362 { applesmc_dmi_match
, "Apple MacBook Air", {
1363 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1364 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookAir") },
1365 &applesmc_dmi_data
[7]},
1366 { applesmc_dmi_match
, "Apple MacBook Pro 5", {
1367 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1368 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro5") },
1369 &applesmc_dmi_data
[12]},
1370 { applesmc_dmi_match
, "Apple MacBook Pro 4", {
1371 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1372 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro4") },
1373 &applesmc_dmi_data
[8]},
1374 { applesmc_dmi_match
, "Apple MacBook Pro 3", {
1375 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1376 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro3") },
1377 &applesmc_dmi_data
[9]},
1378 { applesmc_dmi_match
, "Apple MacBook Pro", {
1379 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1380 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBookPro") },
1381 &applesmc_dmi_data
[0]},
1382 { applesmc_dmi_match
, "Apple MacBook (v2)", {
1383 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1384 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook2") },
1385 &applesmc_dmi_data
[1]},
1386 { applesmc_dmi_match
, "Apple MacBook (v3)", {
1387 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1388 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook3") },
1389 &applesmc_dmi_data
[6]},
1390 { applesmc_dmi_match
, "Apple MacBook 4", {
1391 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1392 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBook4") },
1393 &applesmc_dmi_data
[6]},
1394 { applesmc_dmi_match
, "Apple MacBook 5", {
1395 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1396 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBook5") },
1397 &applesmc_dmi_data
[11]},
1398 { applesmc_dmi_match
, "Apple MacBook", {
1399 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1400 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook") },
1401 &applesmc_dmi_data
[2]},
1402 { applesmc_dmi_match
, "Apple Macmini", {
1403 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1404 DMI_MATCH(DMI_PRODUCT_NAME
,"Macmini") },
1405 &applesmc_dmi_data
[3]},
1406 { applesmc_dmi_match
, "Apple MacPro2", {
1407 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1408 DMI_MATCH(DMI_PRODUCT_NAME
,"MacPro2") },
1409 &applesmc_dmi_data
[4]},
1410 { applesmc_dmi_match
, "Apple MacPro3", {
1411 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1412 DMI_MATCH(DMI_PRODUCT_NAME
, "MacPro3") },
1413 &applesmc_dmi_data
[16]},
1414 { applesmc_dmi_match
, "Apple MacPro", {
1415 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1416 DMI_MATCH(DMI_PRODUCT_NAME
, "MacPro") },
1417 &applesmc_dmi_data
[4]},
1418 { applesmc_dmi_match
, "Apple iMac 8", {
1419 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1420 DMI_MATCH(DMI_PRODUCT_NAME
, "iMac8") },
1421 &applesmc_dmi_data
[13]},
1422 { applesmc_dmi_match
, "Apple iMac 6", {
1423 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1424 DMI_MATCH(DMI_PRODUCT_NAME
, "iMac6") },
1425 &applesmc_dmi_data
[14]},
1426 { applesmc_dmi_match
, "Apple iMac 5", {
1427 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1428 DMI_MATCH(DMI_PRODUCT_NAME
, "iMac5") },
1429 &applesmc_dmi_data
[10]},
1430 { applesmc_dmi_match
, "Apple iMac", {
1431 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1432 DMI_MATCH(DMI_PRODUCT_NAME
,"iMac") },
1433 &applesmc_dmi_data
[5]},
1437 static int __init
applesmc_init(void)
1443 if (!dmi_check_system(applesmc_whitelist
)) {
1444 printk(KERN_WARNING
"applesmc: supported laptop not found!\n");
1449 if (!request_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
,
1455 ret
= platform_driver_register(&applesmc_driver
);
1459 pdev
= platform_device_register_simple("applesmc", APPLESMC_DATA_PORT
,
1462 ret
= PTR_ERR(pdev
);
1466 ret
= sysfs_create_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1470 /* Create key enumeration sysfs files */
1471 ret
= sysfs_create_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1475 /* create fan files */
1476 count
= applesmc_get_fan_count();
1478 printk(KERN_ERR
"applesmc: Cannot get the number of fans.\n");
1480 printk(KERN_INFO
"applesmc: %d fans found.\n", count
);
1484 printk(KERN_WARNING
"applesmc: More than 4 fans found,"
1485 " but at most 4 fans are supported"
1486 " by the driver.\n");
1488 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1489 &fan_attribute_groups
[3]);
1491 goto out_key_enumeration
;
1493 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1494 &fan_attribute_groups
[2]);
1496 goto out_key_enumeration
;
1498 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1499 &fan_attribute_groups
[1]);
1501 goto out_key_enumeration
;
1503 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1504 &fan_attribute_groups
[0]);
1513 temperature_sensors_sets
[applesmc_temperature_set
][i
] != NULL
;
1515 if (temperature_attributes
[i
] == NULL
) {
1516 printk(KERN_ERR
"applesmc: More temperature sensors "
1517 "in temperature_sensors_sets (at least %i)"
1518 "than available sysfs files in "
1519 "temperature_attributes (%i), please report "
1520 "this bug.\n", i
, i
-1);
1521 goto out_temperature
;
1523 ret
= sysfs_create_file(&pdev
->dev
.kobj
,
1524 temperature_attributes
[i
]);
1526 goto out_temperature
;
1529 if (applesmc_accelerometer
) {
1530 ret
= applesmc_create_accelerometer();
1532 goto out_temperature
;
1535 if (applesmc_light
) {
1536 /* Add light sensor file */
1537 ret
= sysfs_create_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1539 goto out_accelerometer
;
1541 /* Create the workqueue */
1542 applesmc_led_wq
= create_singlethread_workqueue("applesmc-led");
1543 if (!applesmc_led_wq
) {
1545 goto out_light_sysfs
;
1548 /* register as a led device */
1549 ret
= led_classdev_register(&pdev
->dev
, &applesmc_backlight
);
1554 hwmon_dev
= hwmon_device_register(&pdev
->dev
);
1555 if (IS_ERR(hwmon_dev
)) {
1556 ret
= PTR_ERR(hwmon_dev
);
1557 goto out_light_ledclass
;
1560 printk(KERN_INFO
"applesmc: driver successfully loaded.\n");
1566 led_classdev_unregister(&applesmc_backlight
);
1569 destroy_workqueue(applesmc_led_wq
);
1572 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1574 if (applesmc_accelerometer
)
1575 applesmc_release_accelerometer();
1577 sysfs_remove_group(&pdev
->dev
.kobj
, &temperature_attributes_group
);
1578 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[0]);
1580 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[1]);
1581 out_key_enumeration
:
1582 sysfs_remove_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1584 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1586 platform_device_unregister(pdev
);
1588 platform_driver_unregister(&applesmc_driver
);
1590 release_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
);
1592 printk(KERN_WARNING
"applesmc: driver init failed (ret=%d)!\n", ret
);
1596 static void __exit
applesmc_exit(void)
1598 hwmon_device_unregister(hwmon_dev
);
1599 if (applesmc_light
) {
1600 led_classdev_unregister(&applesmc_backlight
);
1601 destroy_workqueue(applesmc_led_wq
);
1602 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1604 if (applesmc_accelerometer
)
1605 applesmc_release_accelerometer();
1606 sysfs_remove_group(&pdev
->dev
.kobj
, &temperature_attributes_group
);
1607 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[0]);
1608 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[1]);
1609 sysfs_remove_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1610 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1611 platform_device_unregister(pdev
);
1612 platform_driver_unregister(&applesmc_driver
);
1613 release_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
);
1615 printk(KERN_INFO
"applesmc: driver unloaded.\n");
1618 module_init(applesmc_init
);
1619 module_exit(applesmc_exit
);
1621 MODULE_AUTHOR("Nicolas Boichat");
1622 MODULE_DESCRIPTION("Apple SMC");
1623 MODULE_LICENSE("GPL v2");
1624 MODULE_DEVICE_TABLE(dmi
, applesmc_whitelist
);