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
},
153 /* List of keys used to read/write fan speeds */
154 static const char* fan_speed_keys
[] = {
162 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
163 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
165 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
166 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
167 #define APPLESMC_INPUT_FLAT 4
173 /* Structure to be passed to DMI_MATCH function */
174 struct dmi_match_data
{
175 /* Indicates whether this computer has an accelerometer. */
177 /* Indicates whether this computer has light sensors and keyboard backlight. */
179 /* Indicates which temperature sensors set to use. */
183 static const int debug
;
184 static struct platform_device
*pdev
;
187 static u8 backlight_state
[2];
189 static struct device
*hwmon_dev
;
190 static struct input_polled_dev
*applesmc_idev
;
192 /* Indicates whether this computer has an accelerometer. */
193 static unsigned int applesmc_accelerometer
;
195 /* Indicates whether this computer has light sensors and keyboard backlight. */
196 static unsigned int applesmc_light
;
198 /* Indicates which temperature sensors set to use. */
199 static unsigned int applesmc_temperature_set
;
201 static DEFINE_MUTEX(applesmc_lock
);
204 * Last index written to key_at_index sysfs file, and value to use for all other
205 * key_at_index_* sysfs files.
207 static unsigned int key_at_index
;
209 static struct workqueue_struct
*applesmc_led_wq
;
212 * __wait_status - Wait up to 32ms for the status port to get a certain value
213 * (masked with 0x0f), returning zero if the value is obtained. Callers must
214 * hold applesmc_lock.
216 static int __wait_status(u8 val
)
220 val
= val
& APPLESMC_STATUS_MASK
;
222 for (us
= APPLESMC_MIN_WAIT
; us
< APPLESMC_MAX_WAIT
; us
<<= 1) {
224 if ((inb(APPLESMC_CMD_PORT
) & APPLESMC_STATUS_MASK
) == val
) {
227 "Waited %d us for status %x\n",
228 2 * us
- APPLESMC_MIN_WAIT
, val
);
233 printk(KERN_WARNING
"applesmc: wait status failed: %x != %x\n",
234 val
, inb(APPLESMC_CMD_PORT
));
240 * special treatment of command port - on newer macbooks, it seems necessary
241 * to resend the command byte before polling the status again. Callers must
242 * hold applesmc_lock.
244 static int send_command(u8 cmd
)
247 for (us
= APPLESMC_MIN_WAIT
; us
< APPLESMC_MAX_WAIT
; us
<<= 1) {
248 outb(cmd
, APPLESMC_CMD_PORT
);
250 if ((inb(APPLESMC_CMD_PORT
) & APPLESMC_STATUS_MASK
) == 0x0c)
253 printk(KERN_WARNING
"applesmc: command failed: %x -> %x\n",
254 cmd
, inb(APPLESMC_CMD_PORT
));
259 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
260 * Returns zero on success or a negative error on failure. Callers must
261 * hold applesmc_lock.
263 static int applesmc_read_key(const char* key
, u8
* buffer
, u8 len
)
267 if (len
> APPLESMC_MAX_DATA_LENGTH
) {
268 printk(KERN_ERR
"applesmc_read_key: cannot read more than "
269 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH
);
273 if (send_command(APPLESMC_READ_CMD
))
276 for (i
= 0; i
< 4; i
++) {
277 outb(key
[i
], APPLESMC_DATA_PORT
);
278 if (__wait_status(0x04))
282 printk(KERN_DEBUG
"<%s", key
);
284 outb(len
, APPLESMC_DATA_PORT
);
286 printk(KERN_DEBUG
">%x", len
);
288 for (i
= 0; i
< len
; i
++) {
289 if (__wait_status(0x05))
291 buffer
[i
] = inb(APPLESMC_DATA_PORT
);
293 printk(KERN_DEBUG
"<%x", buffer
[i
]);
296 printk(KERN_DEBUG
"\n");
302 * applesmc_write_key - writes len bytes from buffer to a given key.
303 * Returns zero on success or a negative error on failure. Callers must
304 * hold applesmc_lock.
306 static int applesmc_write_key(const char* key
, u8
* buffer
, u8 len
)
310 if (len
> APPLESMC_MAX_DATA_LENGTH
) {
311 printk(KERN_ERR
"applesmc_write_key: cannot write more than "
312 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH
);
316 if (send_command(APPLESMC_WRITE_CMD
))
319 for (i
= 0; i
< 4; i
++) {
320 outb(key
[i
], APPLESMC_DATA_PORT
);
321 if (__wait_status(0x04))
325 outb(len
, APPLESMC_DATA_PORT
);
327 for (i
= 0; i
< len
; i
++) {
328 if (__wait_status(0x04))
330 outb(buffer
[i
], APPLESMC_DATA_PORT
);
337 * applesmc_get_key_at_index - get key at index, and put the result in key
338 * (char[6]). Returns zero on success or a negative error on failure. Callers
339 * must hold applesmc_lock.
341 static int applesmc_get_key_at_index(int index
, char* key
)
345 readkey
[0] = index
>> 24;
346 readkey
[1] = index
>> 16;
347 readkey
[2] = index
>> 8;
350 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD
))
353 for (i
= 0; i
< 4; i
++) {
354 outb(readkey
[i
], APPLESMC_DATA_PORT
);
355 if (__wait_status(0x04))
359 outb(4, APPLESMC_DATA_PORT
);
361 for (i
= 0; i
< 4; i
++) {
362 if (__wait_status(0x05))
364 key
[i
] = inb(APPLESMC_DATA_PORT
);
372 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
373 * Returns zero on success or a negative error on failure. Callers must
374 * hold applesmc_lock.
376 static int applesmc_get_key_type(char* key
, char* type
)
380 if (send_command(APPLESMC_GET_KEY_TYPE_CMD
))
383 for (i
= 0; i
< 4; i
++) {
384 outb(key
[i
], APPLESMC_DATA_PORT
);
385 if (__wait_status(0x04))
389 outb(6, APPLESMC_DATA_PORT
);
391 for (i
= 0; i
< 6; i
++) {
392 if (__wait_status(0x05))
394 type
[i
] = inb(APPLESMC_DATA_PORT
);
402 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
403 * hold applesmc_lock.
405 static int applesmc_read_motion_sensor(int index
, s16
* value
)
412 ret
= applesmc_read_key(MOTION_SENSOR_X_KEY
, buffer
, 2);
415 ret
= applesmc_read_key(MOTION_SENSOR_Y_KEY
, buffer
, 2);
418 ret
= applesmc_read_key(MOTION_SENSOR_Z_KEY
, buffer
, 2);
424 *value
= ((s16
)buffer
[0] << 8) | buffer
[1];
430 * applesmc_device_init - initialize the accelerometer. Returns zero on success
431 * and negative error code on failure. Can sleep.
433 static int applesmc_device_init(void)
435 int total
, ret
= -ENXIO
;
438 if (!applesmc_accelerometer
)
441 mutex_lock(&applesmc_lock
);
443 for (total
= INIT_TIMEOUT_MSECS
; total
> 0; total
-= INIT_WAIT_MSECS
) {
445 printk(KERN_DEBUG
"applesmc try %d\n", total
);
446 if (!applesmc_read_key(MOTION_SENSOR_KEY
, buffer
, 2) &&
447 (buffer
[0] != 0x00 || buffer
[1] != 0x00)) {
448 if (total
== INIT_TIMEOUT_MSECS
) {
449 printk(KERN_DEBUG
"applesmc: device has"
450 " already been initialized"
451 " (0x%02x, 0x%02x).\n",
452 buffer
[0], buffer
[1]);
454 printk(KERN_DEBUG
"applesmc: device"
455 " successfully initialized"
456 " (0x%02x, 0x%02x).\n",
457 buffer
[0], buffer
[1]);
464 applesmc_write_key(MOTION_SENSOR_KEY
, buffer
, 2);
465 msleep(INIT_WAIT_MSECS
);
468 printk(KERN_WARNING
"applesmc: failed to init the device\n");
471 mutex_unlock(&applesmc_lock
);
476 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
479 static int applesmc_get_fan_count(void)
484 mutex_lock(&applesmc_lock
);
486 ret
= applesmc_read_key(FANS_COUNT
, buffer
, 1);
488 mutex_unlock(&applesmc_lock
);
495 /* Device model stuff */
496 static int applesmc_probe(struct platform_device
*dev
)
500 ret
= applesmc_device_init();
504 printk(KERN_INFO
"applesmc: device successfully initialized.\n");
508 /* Synchronize device with memorized backlight state */
509 static int applesmc_pm_resume(struct device
*dev
)
511 mutex_lock(&applesmc_lock
);
513 applesmc_write_key(BACKLIGHT_KEY
, backlight_state
, 2);
514 mutex_unlock(&applesmc_lock
);
518 /* Reinitialize device on resume from hibernation */
519 static int applesmc_pm_restore(struct device
*dev
)
521 int ret
= applesmc_device_init();
524 return applesmc_pm_resume(dev
);
527 static const struct dev_pm_ops applesmc_pm_ops
= {
528 .resume
= applesmc_pm_resume
,
529 .restore
= applesmc_pm_restore
,
532 static struct platform_driver applesmc_driver
= {
533 .probe
= applesmc_probe
,
536 .owner
= THIS_MODULE
,
537 .pm
= &applesmc_pm_ops
,
542 * applesmc_calibrate - Set our "resting" values. Callers must
543 * hold applesmc_lock.
545 static void applesmc_calibrate(void)
547 applesmc_read_motion_sensor(SENSOR_X
, &rest_x
);
548 applesmc_read_motion_sensor(SENSOR_Y
, &rest_y
);
552 static void applesmc_idev_poll(struct input_polled_dev
*dev
)
554 struct input_dev
*idev
= dev
->input
;
557 mutex_lock(&applesmc_lock
);
559 if (applesmc_read_motion_sensor(SENSOR_X
, &x
))
561 if (applesmc_read_motion_sensor(SENSOR_Y
, &y
))
565 input_report_abs(idev
, ABS_X
, x
- rest_x
);
566 input_report_abs(idev
, ABS_Y
, y
- rest_y
);
570 mutex_unlock(&applesmc_lock
);
575 static ssize_t
applesmc_name_show(struct device
*dev
,
576 struct device_attribute
*attr
, char *buf
)
578 return snprintf(buf
, PAGE_SIZE
, "applesmc\n");
581 static ssize_t
applesmc_position_show(struct device
*dev
,
582 struct device_attribute
*attr
, char *buf
)
587 mutex_lock(&applesmc_lock
);
589 ret
= applesmc_read_motion_sensor(SENSOR_X
, &x
);
592 ret
= applesmc_read_motion_sensor(SENSOR_Y
, &y
);
595 ret
= applesmc_read_motion_sensor(SENSOR_Z
, &z
);
600 mutex_unlock(&applesmc_lock
);
604 return snprintf(buf
, PAGE_SIZE
, "(%d,%d,%d)\n", x
, y
, z
);
607 static ssize_t
applesmc_light_show(struct device
*dev
,
608 struct device_attribute
*attr
, char *sysfsbuf
)
610 static int data_length
;
612 u8 left
= 0, right
= 0;
613 u8 buffer
[10], query
[6];
615 mutex_lock(&applesmc_lock
);
618 ret
= applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY
, query
);
621 data_length
= clamp_val(query
[0], 0, 10);
622 printk(KERN_INFO
"applesmc: light sensor data length set to "
623 "%d\n", data_length
);
626 ret
= applesmc_read_key(LIGHT_SENSOR_LEFT_KEY
, buffer
, data_length
);
627 /* newer macbooks report a single 10-bit bigendian value */
628 if (data_length
== 10) {
629 left
= be16_to_cpu(*(__be16
*)(buffer
+ 6)) >> 2;
635 ret
= applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY
, buffer
, data_length
);
639 mutex_unlock(&applesmc_lock
);
643 return snprintf(sysfsbuf
, PAGE_SIZE
, "(%d,%d)\n", left
, right
);
646 /* Displays degree Celsius * 1000 */
647 static ssize_t
applesmc_show_temperature(struct device
*dev
,
648 struct device_attribute
*devattr
, char *sysfsbuf
)
653 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
655 temperature_sensors_sets
[applesmc_temperature_set
][attr
->index
];
657 mutex_lock(&applesmc_lock
);
659 ret
= applesmc_read_key(key
, buffer
, 2);
660 temp
= buffer
[0]*1000;
661 temp
+= (buffer
[1] >> 6) * 250;
663 mutex_unlock(&applesmc_lock
);
668 return snprintf(sysfsbuf
, PAGE_SIZE
, "%u\n", temp
);
671 static ssize_t
applesmc_show_fan_speed(struct device
*dev
,
672 struct device_attribute
*attr
, char *sysfsbuf
)
675 unsigned int speed
= 0;
678 struct sensor_device_attribute_2
*sensor_attr
=
679 to_sensor_dev_attr_2(attr
);
681 newkey
[0] = fan_speed_keys
[sensor_attr
->nr
][0];
682 newkey
[1] = '0' + sensor_attr
->index
;
683 newkey
[2] = fan_speed_keys
[sensor_attr
->nr
][2];
684 newkey
[3] = fan_speed_keys
[sensor_attr
->nr
][3];
687 mutex_lock(&applesmc_lock
);
689 ret
= applesmc_read_key(newkey
, buffer
, 2);
690 speed
= ((buffer
[0] << 8 | buffer
[1]) >> 2);
692 mutex_unlock(&applesmc_lock
);
696 return snprintf(sysfsbuf
, PAGE_SIZE
, "%u\n", speed
);
699 static ssize_t
applesmc_store_fan_speed(struct device
*dev
,
700 struct device_attribute
*attr
,
701 const char *sysfsbuf
, size_t count
)
707 struct sensor_device_attribute_2
*sensor_attr
=
708 to_sensor_dev_attr_2(attr
);
710 speed
= simple_strtoul(sysfsbuf
, NULL
, 10);
712 if (speed
> 0x4000) /* Bigger than a 14-bit value */
715 newkey
[0] = fan_speed_keys
[sensor_attr
->nr
][0];
716 newkey
[1] = '0' + sensor_attr
->index
;
717 newkey
[2] = fan_speed_keys
[sensor_attr
->nr
][2];
718 newkey
[3] = fan_speed_keys
[sensor_attr
->nr
][3];
721 mutex_lock(&applesmc_lock
);
723 buffer
[0] = (speed
>> 6) & 0xff;
724 buffer
[1] = (speed
<< 2) & 0xff;
725 ret
= applesmc_write_key(newkey
, buffer
, 2);
727 mutex_unlock(&applesmc_lock
);
734 static ssize_t
applesmc_show_fan_manual(struct device
*dev
,
735 struct device_attribute
*devattr
, char *sysfsbuf
)
740 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
742 mutex_lock(&applesmc_lock
);
744 ret
= applesmc_read_key(FANS_MANUAL
, buffer
, 2);
745 manual
= ((buffer
[0] << 8 | buffer
[1]) >> attr
->index
) & 0x01;
747 mutex_unlock(&applesmc_lock
);
751 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", manual
);
754 static ssize_t
applesmc_store_fan_manual(struct device
*dev
,
755 struct device_attribute
*devattr
,
756 const char *sysfsbuf
, size_t count
)
762 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
764 input
= simple_strtoul(sysfsbuf
, NULL
, 10);
766 mutex_lock(&applesmc_lock
);
768 ret
= applesmc_read_key(FANS_MANUAL
, buffer
, 2);
769 val
= (buffer
[0] << 8 | buffer
[1]);
774 val
= val
| (0x01 << attr
->index
);
776 val
= val
& ~(0x01 << attr
->index
);
778 buffer
[0] = (val
>> 8) & 0xFF;
779 buffer
[1] = val
& 0xFF;
781 ret
= applesmc_write_key(FANS_MANUAL
, buffer
, 2);
784 mutex_unlock(&applesmc_lock
);
791 static ssize_t
applesmc_show_fan_position(struct device
*dev
,
792 struct device_attribute
*attr
, char *sysfsbuf
)
797 struct sensor_device_attribute_2
*sensor_attr
=
798 to_sensor_dev_attr_2(attr
);
800 newkey
[0] = FAN_POSITION
[0];
801 newkey
[1] = '0' + sensor_attr
->index
;
802 newkey
[2] = FAN_POSITION
[2];
803 newkey
[3] = FAN_POSITION
[3];
806 mutex_lock(&applesmc_lock
);
808 ret
= applesmc_read_key(newkey
, buffer
, 16);
811 mutex_unlock(&applesmc_lock
);
815 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", buffer
+4);
818 static ssize_t
applesmc_calibrate_show(struct device
*dev
,
819 struct device_attribute
*attr
, char *sysfsbuf
)
821 return snprintf(sysfsbuf
, PAGE_SIZE
, "(%d,%d)\n", rest_x
, rest_y
);
824 static ssize_t
applesmc_calibrate_store(struct device
*dev
,
825 struct device_attribute
*attr
, const char *sysfsbuf
, size_t count
)
827 mutex_lock(&applesmc_lock
);
828 applesmc_calibrate();
829 mutex_unlock(&applesmc_lock
);
834 static void applesmc_backlight_set(struct work_struct
*work
)
836 mutex_lock(&applesmc_lock
);
837 applesmc_write_key(BACKLIGHT_KEY
, backlight_state
, 2);
838 mutex_unlock(&applesmc_lock
);
840 static DECLARE_WORK(backlight_work
, &applesmc_backlight_set
);
842 static void applesmc_brightness_set(struct led_classdev
*led_cdev
,
843 enum led_brightness value
)
847 backlight_state
[0] = value
;
848 ret
= queue_work(applesmc_led_wq
, &backlight_work
);
851 printk(KERN_DEBUG
"applesmc: work was already on the queue.\n");
854 static ssize_t
applesmc_key_count_show(struct device
*dev
,
855 struct device_attribute
*attr
, char *sysfsbuf
)
861 mutex_lock(&applesmc_lock
);
863 ret
= applesmc_read_key(KEY_COUNT_KEY
, buffer
, 4);
864 count
= ((u32
)buffer
[0]<<24) + ((u32
)buffer
[1]<<16) +
865 ((u32
)buffer
[2]<<8) + buffer
[3];
867 mutex_unlock(&applesmc_lock
);
871 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", count
);
874 static ssize_t
applesmc_key_at_index_read_show(struct device
*dev
,
875 struct device_attribute
*attr
, char *sysfsbuf
)
881 mutex_lock(&applesmc_lock
);
883 ret
= applesmc_get_key_at_index(key_at_index
, key
);
885 if (ret
|| !key
[0]) {
886 mutex_unlock(&applesmc_lock
);
891 ret
= applesmc_get_key_type(key
, info
);
894 mutex_unlock(&applesmc_lock
);
900 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
901 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
903 ret
= applesmc_read_key(key
, sysfsbuf
, info
[0]);
905 mutex_unlock(&applesmc_lock
);
914 static ssize_t
applesmc_key_at_index_data_length_show(struct device
*dev
,
915 struct device_attribute
*attr
, char *sysfsbuf
)
921 mutex_lock(&applesmc_lock
);
923 ret
= applesmc_get_key_at_index(key_at_index
, key
);
925 if (ret
|| !key
[0]) {
926 mutex_unlock(&applesmc_lock
);
931 ret
= applesmc_get_key_type(key
, info
);
933 mutex_unlock(&applesmc_lock
);
936 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", info
[0]);
941 static ssize_t
applesmc_key_at_index_type_show(struct device
*dev
,
942 struct device_attribute
*attr
, char *sysfsbuf
)
948 mutex_lock(&applesmc_lock
);
950 ret
= applesmc_get_key_at_index(key_at_index
, key
);
952 if (ret
|| !key
[0]) {
953 mutex_unlock(&applesmc_lock
);
958 ret
= applesmc_get_key_type(key
, info
);
960 mutex_unlock(&applesmc_lock
);
963 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", info
+1);
968 static ssize_t
applesmc_key_at_index_name_show(struct device
*dev
,
969 struct device_attribute
*attr
, char *sysfsbuf
)
974 mutex_lock(&applesmc_lock
);
976 ret
= applesmc_get_key_at_index(key_at_index
, key
);
978 mutex_unlock(&applesmc_lock
);
981 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", key
);
986 static ssize_t
applesmc_key_at_index_show(struct device
*dev
,
987 struct device_attribute
*attr
, char *sysfsbuf
)
989 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", key_at_index
);
992 static ssize_t
applesmc_key_at_index_store(struct device
*dev
,
993 struct device_attribute
*attr
, const char *sysfsbuf
, size_t count
)
995 mutex_lock(&applesmc_lock
);
997 key_at_index
= simple_strtoul(sysfsbuf
, NULL
, 10);
999 mutex_unlock(&applesmc_lock
);
1004 static struct led_classdev applesmc_backlight
= {
1005 .name
= "smc::kbd_backlight",
1006 .default_trigger
= "nand-disk",
1007 .brightness_set
= applesmc_brightness_set
,
1010 static DEVICE_ATTR(name
, 0444, applesmc_name_show
, NULL
);
1012 static DEVICE_ATTR(position
, 0444, applesmc_position_show
, NULL
);
1013 static DEVICE_ATTR(calibrate
, 0644,
1014 applesmc_calibrate_show
, applesmc_calibrate_store
);
1016 static struct attribute
*accelerometer_attributes
[] = {
1017 &dev_attr_position
.attr
,
1018 &dev_attr_calibrate
.attr
,
1022 static const struct attribute_group accelerometer_attributes_group
=
1023 { .attrs
= accelerometer_attributes
};
1025 static DEVICE_ATTR(light
, 0444, applesmc_light_show
, NULL
);
1027 static DEVICE_ATTR(key_count
, 0444, applesmc_key_count_show
, NULL
);
1028 static DEVICE_ATTR(key_at_index
, 0644,
1029 applesmc_key_at_index_show
, applesmc_key_at_index_store
);
1030 static DEVICE_ATTR(key_at_index_name
, 0444,
1031 applesmc_key_at_index_name_show
, NULL
);
1032 static DEVICE_ATTR(key_at_index_type
, 0444,
1033 applesmc_key_at_index_type_show
, NULL
);
1034 static DEVICE_ATTR(key_at_index_data_length
, 0444,
1035 applesmc_key_at_index_data_length_show
, NULL
);
1036 static DEVICE_ATTR(key_at_index_data
, 0444,
1037 applesmc_key_at_index_read_show
, NULL
);
1039 static struct attribute
*key_enumeration_attributes
[] = {
1040 &dev_attr_key_count
.attr
,
1041 &dev_attr_key_at_index
.attr
,
1042 &dev_attr_key_at_index_name
.attr
,
1043 &dev_attr_key_at_index_type
.attr
,
1044 &dev_attr_key_at_index_data_length
.attr
,
1045 &dev_attr_key_at_index_data
.attr
,
1049 static const struct attribute_group key_enumeration_group
=
1050 { .attrs
= key_enumeration_attributes
};
1053 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1054 * - show actual speed
1055 * - show/store minimum speed
1056 * - show maximum speed
1058 * - show/store target speed
1059 * - show/store manual mode
1061 #define sysfs_fan_speeds_offset(offset) \
1062 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1063 applesmc_show_fan_speed, NULL, 0, offset-1); \
1065 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1066 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1068 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1069 applesmc_show_fan_speed, NULL, 2, offset-1); \
1071 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1072 applesmc_show_fan_speed, NULL, 3, offset-1); \
1074 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1075 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1077 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1078 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1080 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1081 applesmc_show_fan_position, NULL, offset-1); \
1083 static struct attribute *fan##offset##_attributes[] = { \
1084 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1085 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1086 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1087 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1088 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1089 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1090 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1095 * Create the needed functions for each fan using the macro defined above
1096 * (4 fans are supported)
1098 sysfs_fan_speeds_offset(1);
1099 sysfs_fan_speeds_offset(2);
1100 sysfs_fan_speeds_offset(3);
1101 sysfs_fan_speeds_offset(4);
1103 static const struct attribute_group fan_attribute_groups
[] = {
1104 { .attrs
= fan1_attributes
},
1105 { .attrs
= fan2_attributes
},
1106 { .attrs
= fan3_attributes
},
1107 { .attrs
= fan4_attributes
},
1111 * Temperature sensors sysfs entries.
1113 static SENSOR_DEVICE_ATTR(temp1_input
, S_IRUGO
,
1114 applesmc_show_temperature
, NULL
, 0);
1115 static SENSOR_DEVICE_ATTR(temp2_input
, S_IRUGO
,
1116 applesmc_show_temperature
, NULL
, 1);
1117 static SENSOR_DEVICE_ATTR(temp3_input
, S_IRUGO
,
1118 applesmc_show_temperature
, NULL
, 2);
1119 static SENSOR_DEVICE_ATTR(temp4_input
, S_IRUGO
,
1120 applesmc_show_temperature
, NULL
, 3);
1121 static SENSOR_DEVICE_ATTR(temp5_input
, S_IRUGO
,
1122 applesmc_show_temperature
, NULL
, 4);
1123 static SENSOR_DEVICE_ATTR(temp6_input
, S_IRUGO
,
1124 applesmc_show_temperature
, NULL
, 5);
1125 static SENSOR_DEVICE_ATTR(temp7_input
, S_IRUGO
,
1126 applesmc_show_temperature
, NULL
, 6);
1127 static SENSOR_DEVICE_ATTR(temp8_input
, S_IRUGO
,
1128 applesmc_show_temperature
, NULL
, 7);
1129 static SENSOR_DEVICE_ATTR(temp9_input
, S_IRUGO
,
1130 applesmc_show_temperature
, NULL
, 8);
1131 static SENSOR_DEVICE_ATTR(temp10_input
, S_IRUGO
,
1132 applesmc_show_temperature
, NULL
, 9);
1133 static SENSOR_DEVICE_ATTR(temp11_input
, S_IRUGO
,
1134 applesmc_show_temperature
, NULL
, 10);
1135 static SENSOR_DEVICE_ATTR(temp12_input
, S_IRUGO
,
1136 applesmc_show_temperature
, NULL
, 11);
1137 static SENSOR_DEVICE_ATTR(temp13_input
, S_IRUGO
,
1138 applesmc_show_temperature
, NULL
, 12);
1139 static SENSOR_DEVICE_ATTR(temp14_input
, S_IRUGO
,
1140 applesmc_show_temperature
, NULL
, 13);
1141 static SENSOR_DEVICE_ATTR(temp15_input
, S_IRUGO
,
1142 applesmc_show_temperature
, NULL
, 14);
1143 static SENSOR_DEVICE_ATTR(temp16_input
, S_IRUGO
,
1144 applesmc_show_temperature
, NULL
, 15);
1145 static SENSOR_DEVICE_ATTR(temp17_input
, S_IRUGO
,
1146 applesmc_show_temperature
, NULL
, 16);
1147 static SENSOR_DEVICE_ATTR(temp18_input
, S_IRUGO
,
1148 applesmc_show_temperature
, NULL
, 17);
1149 static SENSOR_DEVICE_ATTR(temp19_input
, S_IRUGO
,
1150 applesmc_show_temperature
, NULL
, 18);
1151 static SENSOR_DEVICE_ATTR(temp20_input
, S_IRUGO
,
1152 applesmc_show_temperature
, NULL
, 19);
1153 static SENSOR_DEVICE_ATTR(temp21_input
, S_IRUGO
,
1154 applesmc_show_temperature
, NULL
, 20);
1155 static SENSOR_DEVICE_ATTR(temp22_input
, S_IRUGO
,
1156 applesmc_show_temperature
, NULL
, 21);
1157 static SENSOR_DEVICE_ATTR(temp23_input
, S_IRUGO
,
1158 applesmc_show_temperature
, NULL
, 22);
1159 static SENSOR_DEVICE_ATTR(temp24_input
, S_IRUGO
,
1160 applesmc_show_temperature
, NULL
, 23);
1161 static SENSOR_DEVICE_ATTR(temp25_input
, S_IRUGO
,
1162 applesmc_show_temperature
, NULL
, 24);
1163 static SENSOR_DEVICE_ATTR(temp26_input
, S_IRUGO
,
1164 applesmc_show_temperature
, NULL
, 25);
1165 static SENSOR_DEVICE_ATTR(temp27_input
, S_IRUGO
,
1166 applesmc_show_temperature
, NULL
, 26);
1167 static SENSOR_DEVICE_ATTR(temp28_input
, S_IRUGO
,
1168 applesmc_show_temperature
, NULL
, 27);
1169 static SENSOR_DEVICE_ATTR(temp29_input
, S_IRUGO
,
1170 applesmc_show_temperature
, NULL
, 28);
1171 static SENSOR_DEVICE_ATTR(temp30_input
, S_IRUGO
,
1172 applesmc_show_temperature
, NULL
, 29);
1173 static SENSOR_DEVICE_ATTR(temp31_input
, S_IRUGO
,
1174 applesmc_show_temperature
, NULL
, 30);
1175 static SENSOR_DEVICE_ATTR(temp32_input
, S_IRUGO
,
1176 applesmc_show_temperature
, NULL
, 31);
1177 static SENSOR_DEVICE_ATTR(temp33_input
, S_IRUGO
,
1178 applesmc_show_temperature
, NULL
, 32);
1179 static SENSOR_DEVICE_ATTR(temp34_input
, S_IRUGO
,
1180 applesmc_show_temperature
, NULL
, 33);
1181 static SENSOR_DEVICE_ATTR(temp35_input
, S_IRUGO
,
1182 applesmc_show_temperature
, NULL
, 34);
1183 static SENSOR_DEVICE_ATTR(temp36_input
, S_IRUGO
,
1184 applesmc_show_temperature
, NULL
, 35);
1185 static SENSOR_DEVICE_ATTR(temp37_input
, S_IRUGO
,
1186 applesmc_show_temperature
, NULL
, 36);
1187 static SENSOR_DEVICE_ATTR(temp38_input
, S_IRUGO
,
1188 applesmc_show_temperature
, NULL
, 37);
1189 static SENSOR_DEVICE_ATTR(temp39_input
, S_IRUGO
,
1190 applesmc_show_temperature
, NULL
, 38);
1191 static SENSOR_DEVICE_ATTR(temp40_input
, S_IRUGO
,
1192 applesmc_show_temperature
, NULL
, 39);
1194 static struct attribute
*temperature_attributes
[] = {
1195 &sensor_dev_attr_temp1_input
.dev_attr
.attr
,
1196 &sensor_dev_attr_temp2_input
.dev_attr
.attr
,
1197 &sensor_dev_attr_temp3_input
.dev_attr
.attr
,
1198 &sensor_dev_attr_temp4_input
.dev_attr
.attr
,
1199 &sensor_dev_attr_temp5_input
.dev_attr
.attr
,
1200 &sensor_dev_attr_temp6_input
.dev_attr
.attr
,
1201 &sensor_dev_attr_temp7_input
.dev_attr
.attr
,
1202 &sensor_dev_attr_temp8_input
.dev_attr
.attr
,
1203 &sensor_dev_attr_temp9_input
.dev_attr
.attr
,
1204 &sensor_dev_attr_temp10_input
.dev_attr
.attr
,
1205 &sensor_dev_attr_temp11_input
.dev_attr
.attr
,
1206 &sensor_dev_attr_temp12_input
.dev_attr
.attr
,
1207 &sensor_dev_attr_temp13_input
.dev_attr
.attr
,
1208 &sensor_dev_attr_temp14_input
.dev_attr
.attr
,
1209 &sensor_dev_attr_temp15_input
.dev_attr
.attr
,
1210 &sensor_dev_attr_temp16_input
.dev_attr
.attr
,
1211 &sensor_dev_attr_temp17_input
.dev_attr
.attr
,
1212 &sensor_dev_attr_temp18_input
.dev_attr
.attr
,
1213 &sensor_dev_attr_temp19_input
.dev_attr
.attr
,
1214 &sensor_dev_attr_temp20_input
.dev_attr
.attr
,
1215 &sensor_dev_attr_temp21_input
.dev_attr
.attr
,
1216 &sensor_dev_attr_temp22_input
.dev_attr
.attr
,
1217 &sensor_dev_attr_temp23_input
.dev_attr
.attr
,
1218 &sensor_dev_attr_temp24_input
.dev_attr
.attr
,
1219 &sensor_dev_attr_temp25_input
.dev_attr
.attr
,
1220 &sensor_dev_attr_temp26_input
.dev_attr
.attr
,
1221 &sensor_dev_attr_temp27_input
.dev_attr
.attr
,
1222 &sensor_dev_attr_temp28_input
.dev_attr
.attr
,
1223 &sensor_dev_attr_temp29_input
.dev_attr
.attr
,
1224 &sensor_dev_attr_temp30_input
.dev_attr
.attr
,
1225 &sensor_dev_attr_temp31_input
.dev_attr
.attr
,
1226 &sensor_dev_attr_temp32_input
.dev_attr
.attr
,
1227 &sensor_dev_attr_temp33_input
.dev_attr
.attr
,
1228 &sensor_dev_attr_temp34_input
.dev_attr
.attr
,
1229 &sensor_dev_attr_temp35_input
.dev_attr
.attr
,
1230 &sensor_dev_attr_temp36_input
.dev_attr
.attr
,
1231 &sensor_dev_attr_temp37_input
.dev_attr
.attr
,
1232 &sensor_dev_attr_temp38_input
.dev_attr
.attr
,
1233 &sensor_dev_attr_temp39_input
.dev_attr
.attr
,
1234 &sensor_dev_attr_temp40_input
.dev_attr
.attr
,
1238 static const struct attribute_group temperature_attributes_group
=
1239 { .attrs
= temperature_attributes
};
1244 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1246 static int applesmc_dmi_match(const struct dmi_system_id
*id
)
1249 struct dmi_match_data
* dmi_data
= id
->driver_data
;
1250 printk(KERN_INFO
"applesmc: %s detected:\n", id
->ident
);
1251 applesmc_accelerometer
= dmi_data
->accelerometer
;
1252 printk(KERN_INFO
"applesmc: - Model %s accelerometer\n",
1253 applesmc_accelerometer
? "with" : "without");
1254 applesmc_light
= dmi_data
->light
;
1255 printk(KERN_INFO
"applesmc: - Model %s light sensors and backlight\n",
1256 applesmc_light
? "with" : "without");
1258 applesmc_temperature_set
= dmi_data
->temperature_set
;
1259 while (temperature_sensors_sets
[applesmc_temperature_set
][i
] != NULL
)
1261 printk(KERN_INFO
"applesmc: - Model with %d temperature sensors\n", i
);
1265 /* Create accelerometer ressources */
1266 static int applesmc_create_accelerometer(void)
1268 struct input_dev
*idev
;
1271 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1272 &accelerometer_attributes_group
);
1276 applesmc_idev
= input_allocate_polled_device();
1277 if (!applesmc_idev
) {
1282 applesmc_idev
->poll
= applesmc_idev_poll
;
1283 applesmc_idev
->poll_interval
= APPLESMC_POLL_INTERVAL
;
1285 /* initial calibrate for the input device */
1286 applesmc_calibrate();
1288 /* initialize the input device */
1289 idev
= applesmc_idev
->input
;
1290 idev
->name
= "applesmc";
1291 idev
->id
.bustype
= BUS_HOST
;
1292 idev
->dev
.parent
= &pdev
->dev
;
1293 idev
->evbit
[0] = BIT_MASK(EV_ABS
);
1294 input_set_abs_params(idev
, ABS_X
,
1295 -256, 256, APPLESMC_INPUT_FUZZ
, APPLESMC_INPUT_FLAT
);
1296 input_set_abs_params(idev
, ABS_Y
,
1297 -256, 256, APPLESMC_INPUT_FUZZ
, APPLESMC_INPUT_FLAT
);
1299 ret
= input_register_polled_device(applesmc_idev
);
1306 input_free_polled_device(applesmc_idev
);
1309 sysfs_remove_group(&pdev
->dev
.kobj
, &accelerometer_attributes_group
);
1312 printk(KERN_WARNING
"applesmc: driver init failed (ret=%d)!\n", ret
);
1316 /* Release all ressources used by the accelerometer */
1317 static void applesmc_release_accelerometer(void)
1319 input_unregister_polled_device(applesmc_idev
);
1320 input_free_polled_device(applesmc_idev
);
1321 sysfs_remove_group(&pdev
->dev
.kobj
, &accelerometer_attributes_group
);
1324 static __initdata
struct dmi_match_data applesmc_dmi_data
[] = {
1325 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1326 { .accelerometer
= 1, .light
= 1, .temperature_set
= 0 },
1327 /* MacBook2: accelerometer and temperature set 1 */
1328 { .accelerometer
= 1, .light
= 0, .temperature_set
= 1 },
1329 /* MacBook: accelerometer and temperature set 2 */
1330 { .accelerometer
= 1, .light
= 0, .temperature_set
= 2 },
1331 /* MacMini: temperature set 3 */
1332 { .accelerometer
= 0, .light
= 0, .temperature_set
= 3 },
1333 /* MacPro: temperature set 4 */
1334 { .accelerometer
= 0, .light
= 0, .temperature_set
= 4 },
1335 /* iMac: temperature set 5 */
1336 { .accelerometer
= 0, .light
= 0, .temperature_set
= 5 },
1337 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1338 { .accelerometer
= 1, .light
= 0, .temperature_set
= 6 },
1339 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1340 { .accelerometer
= 1, .light
= 1, .temperature_set
= 7 },
1341 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1342 { .accelerometer
= 1, .light
= 1, .temperature_set
= 8 },
1343 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1344 { .accelerometer
= 1, .light
= 1, .temperature_set
= 9 },
1345 /* iMac 5: light sensor only, temperature set 10 */
1346 { .accelerometer
= 0, .light
= 0, .temperature_set
= 10 },
1347 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1348 { .accelerometer
= 1, .light
= 1, .temperature_set
= 11 },
1349 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1350 { .accelerometer
= 1, .light
= 1, .temperature_set
= 12 },
1351 /* iMac 8: light sensor only, temperature set 13 */
1352 { .accelerometer
= 0, .light
= 0, .temperature_set
= 13 },
1353 /* iMac 6: light sensor only, temperature set 14 */
1354 { .accelerometer
= 0, .light
= 0, .temperature_set
= 14 },
1355 /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
1356 { .accelerometer
= 1, .light
= 1, .temperature_set
= 15 },
1357 /* MacPro3,1: temperature set 16 */
1358 { .accelerometer
= 0, .light
= 0, .temperature_set
= 16 },
1359 /* iMac 9,1: light sensor only, temperature set 17 */
1360 { .accelerometer
= 0, .light
= 0, .temperature_set
= 17 },
1361 /* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
1362 { .accelerometer
= 1, .light
= 1, .temperature_set
= 18 },
1365 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1366 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1367 static __initdata
struct dmi_system_id applesmc_whitelist
[] = {
1368 { applesmc_dmi_match
, "Apple MacBook Air 2", {
1369 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1370 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookAir2") },
1371 &applesmc_dmi_data
[15]},
1372 { applesmc_dmi_match
, "Apple MacBook Air", {
1373 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1374 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookAir") },
1375 &applesmc_dmi_data
[7]},
1376 { applesmc_dmi_match
, "Apple MacBook Pro 5", {
1377 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1378 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro5") },
1379 &applesmc_dmi_data
[12]},
1380 { applesmc_dmi_match
, "Apple MacBook Pro 4", {
1381 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1382 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro4") },
1383 &applesmc_dmi_data
[8]},
1384 { applesmc_dmi_match
, "Apple MacBook Pro 3", {
1385 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1386 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro3") },
1387 &applesmc_dmi_data
[9]},
1388 { applesmc_dmi_match
, "Apple MacBook Pro 2,2", {
1389 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple Computer, Inc."),
1390 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro2,2") },
1391 &applesmc_dmi_data
[18]},
1392 { applesmc_dmi_match
, "Apple MacBook Pro", {
1393 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1394 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBookPro") },
1395 &applesmc_dmi_data
[0]},
1396 { applesmc_dmi_match
, "Apple MacBook (v2)", {
1397 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1398 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook2") },
1399 &applesmc_dmi_data
[1]},
1400 { applesmc_dmi_match
, "Apple MacBook (v3)", {
1401 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1402 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook3") },
1403 &applesmc_dmi_data
[6]},
1404 { applesmc_dmi_match
, "Apple MacBook 4", {
1405 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1406 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBook4") },
1407 &applesmc_dmi_data
[6]},
1408 { applesmc_dmi_match
, "Apple MacBook 5", {
1409 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1410 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBook5") },
1411 &applesmc_dmi_data
[11]},
1412 { applesmc_dmi_match
, "Apple MacBook", {
1413 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1414 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook") },
1415 &applesmc_dmi_data
[2]},
1416 { applesmc_dmi_match
, "Apple Macmini", {
1417 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1418 DMI_MATCH(DMI_PRODUCT_NAME
,"Macmini") },
1419 &applesmc_dmi_data
[3]},
1420 { applesmc_dmi_match
, "Apple MacPro2", {
1421 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1422 DMI_MATCH(DMI_PRODUCT_NAME
,"MacPro2") },
1423 &applesmc_dmi_data
[4]},
1424 { applesmc_dmi_match
, "Apple MacPro3", {
1425 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1426 DMI_MATCH(DMI_PRODUCT_NAME
, "MacPro3") },
1427 &applesmc_dmi_data
[16]},
1428 { applesmc_dmi_match
, "Apple MacPro", {
1429 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1430 DMI_MATCH(DMI_PRODUCT_NAME
, "MacPro") },
1431 &applesmc_dmi_data
[4]},
1432 { applesmc_dmi_match
, "Apple iMac 9,1", {
1433 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple Inc."),
1434 DMI_MATCH(DMI_PRODUCT_NAME
, "iMac9,1") },
1435 &applesmc_dmi_data
[17]},
1436 { applesmc_dmi_match
, "Apple iMac 8", {
1437 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1438 DMI_MATCH(DMI_PRODUCT_NAME
, "iMac8") },
1439 &applesmc_dmi_data
[13]},
1440 { applesmc_dmi_match
, "Apple iMac 6", {
1441 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1442 DMI_MATCH(DMI_PRODUCT_NAME
, "iMac6") },
1443 &applesmc_dmi_data
[14]},
1444 { applesmc_dmi_match
, "Apple iMac 5", {
1445 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1446 DMI_MATCH(DMI_PRODUCT_NAME
, "iMac5") },
1447 &applesmc_dmi_data
[10]},
1448 { applesmc_dmi_match
, "Apple iMac", {
1449 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1450 DMI_MATCH(DMI_PRODUCT_NAME
,"iMac") },
1451 &applesmc_dmi_data
[5]},
1455 static int __init
applesmc_init(void)
1461 if (!dmi_check_system(applesmc_whitelist
)) {
1462 printk(KERN_WARNING
"applesmc: supported laptop not found!\n");
1467 if (!request_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
,
1473 ret
= platform_driver_register(&applesmc_driver
);
1477 pdev
= platform_device_register_simple("applesmc", APPLESMC_DATA_PORT
,
1480 ret
= PTR_ERR(pdev
);
1484 ret
= sysfs_create_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1488 /* Create key enumeration sysfs files */
1489 ret
= sysfs_create_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1493 /* create fan files */
1494 count
= applesmc_get_fan_count();
1496 printk(KERN_ERR
"applesmc: Cannot get the number of fans.\n");
1498 printk(KERN_INFO
"applesmc: %d fans found.\n", count
);
1502 printk(KERN_WARNING
"applesmc: More than 4 fans found,"
1503 " but at most 4 fans are supported"
1504 " by the driver.\n");
1506 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1507 &fan_attribute_groups
[3]);
1509 goto out_key_enumeration
;
1511 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1512 &fan_attribute_groups
[2]);
1514 goto out_key_enumeration
;
1516 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1517 &fan_attribute_groups
[1]);
1519 goto out_key_enumeration
;
1521 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1522 &fan_attribute_groups
[0]);
1531 temperature_sensors_sets
[applesmc_temperature_set
][i
] != NULL
;
1533 if (temperature_attributes
[i
] == NULL
) {
1534 printk(KERN_ERR
"applesmc: More temperature sensors "
1535 "in temperature_sensors_sets (at least %i)"
1536 "than available sysfs files in "
1537 "temperature_attributes (%i), please report "
1538 "this bug.\n", i
, i
-1);
1539 goto out_temperature
;
1541 ret
= sysfs_create_file(&pdev
->dev
.kobj
,
1542 temperature_attributes
[i
]);
1544 goto out_temperature
;
1547 if (applesmc_accelerometer
) {
1548 ret
= applesmc_create_accelerometer();
1550 goto out_temperature
;
1553 if (applesmc_light
) {
1554 /* Add light sensor file */
1555 ret
= sysfs_create_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1557 goto out_accelerometer
;
1559 /* Create the workqueue */
1560 applesmc_led_wq
= create_singlethread_workqueue("applesmc-led");
1561 if (!applesmc_led_wq
) {
1563 goto out_light_sysfs
;
1566 /* register as a led device */
1567 ret
= led_classdev_register(&pdev
->dev
, &applesmc_backlight
);
1572 hwmon_dev
= hwmon_device_register(&pdev
->dev
);
1573 if (IS_ERR(hwmon_dev
)) {
1574 ret
= PTR_ERR(hwmon_dev
);
1575 goto out_light_ledclass
;
1578 printk(KERN_INFO
"applesmc: driver successfully loaded.\n");
1584 led_classdev_unregister(&applesmc_backlight
);
1587 destroy_workqueue(applesmc_led_wq
);
1590 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1592 if (applesmc_accelerometer
)
1593 applesmc_release_accelerometer();
1595 sysfs_remove_group(&pdev
->dev
.kobj
, &temperature_attributes_group
);
1596 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[0]);
1598 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[1]);
1599 out_key_enumeration
:
1600 sysfs_remove_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1602 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1604 platform_device_unregister(pdev
);
1606 platform_driver_unregister(&applesmc_driver
);
1608 release_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
);
1610 printk(KERN_WARNING
"applesmc: driver init failed (ret=%d)!\n", ret
);
1614 static void __exit
applesmc_exit(void)
1616 hwmon_device_unregister(hwmon_dev
);
1617 if (applesmc_light
) {
1618 led_classdev_unregister(&applesmc_backlight
);
1619 destroy_workqueue(applesmc_led_wq
);
1620 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1622 if (applesmc_accelerometer
)
1623 applesmc_release_accelerometer();
1624 sysfs_remove_group(&pdev
->dev
.kobj
, &temperature_attributes_group
);
1625 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[0]);
1626 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[1]);
1627 sysfs_remove_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1628 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1629 platform_device_unregister(pdev
);
1630 platform_driver_unregister(&applesmc_driver
);
1631 release_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
);
1633 printk(KERN_INFO
"applesmc: driver unloaded.\n");
1636 module_init(applesmc_init
);
1637 module_exit(applesmc_exit
);
1639 MODULE_AUTHOR("Nicolas Boichat");
1640 MODULE_DESCRIPTION("Apple SMC");
1641 MODULE_LICENSE("GPL v2");
1642 MODULE_DEVICE_TABLE(dmi
, applesmc_whitelist
);