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 /* The number of fans handled by the driver */
199 static unsigned int fans_handled
;
201 /* Indicates which temperature sensors set to use. */
202 static unsigned int applesmc_temperature_set
;
204 static DEFINE_MUTEX(applesmc_lock
);
207 * Last index written to key_at_index sysfs file, and value to use for all other
208 * key_at_index_* sysfs files.
210 static unsigned int key_at_index
;
212 static struct workqueue_struct
*applesmc_led_wq
;
215 * __wait_status - Wait up to 32ms for the status port to get a certain value
216 * (masked with 0x0f), returning zero if the value is obtained. Callers must
217 * hold applesmc_lock.
219 static int __wait_status(u8 val
)
223 val
= val
& APPLESMC_STATUS_MASK
;
225 for (us
= APPLESMC_MIN_WAIT
; us
< APPLESMC_MAX_WAIT
; us
<<= 1) {
227 if ((inb(APPLESMC_CMD_PORT
) & APPLESMC_STATUS_MASK
) == val
) {
230 "Waited %d us for status %x\n",
231 2 * us
- APPLESMC_MIN_WAIT
, val
);
236 printk(KERN_WARNING
"applesmc: wait status failed: %x != %x\n",
237 val
, inb(APPLESMC_CMD_PORT
));
243 * special treatment of command port - on newer macbooks, it seems necessary
244 * to resend the command byte before polling the status again. Callers must
245 * hold applesmc_lock.
247 static int send_command(u8 cmd
)
250 for (us
= APPLESMC_MIN_WAIT
; us
< APPLESMC_MAX_WAIT
; us
<<= 1) {
251 outb(cmd
, APPLESMC_CMD_PORT
);
253 if ((inb(APPLESMC_CMD_PORT
) & APPLESMC_STATUS_MASK
) == 0x0c)
256 printk(KERN_WARNING
"applesmc: command failed: %x -> %x\n",
257 cmd
, inb(APPLESMC_CMD_PORT
));
262 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
263 * Returns zero on success or a negative error on failure. Callers must
264 * hold applesmc_lock.
266 static int applesmc_read_key(const char* key
, u8
* buffer
, u8 len
)
270 if (len
> APPLESMC_MAX_DATA_LENGTH
) {
271 printk(KERN_ERR
"applesmc_read_key: cannot read more than "
272 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH
);
276 if (send_command(APPLESMC_READ_CMD
))
279 for (i
= 0; i
< 4; i
++) {
280 outb(key
[i
], APPLESMC_DATA_PORT
);
281 if (__wait_status(0x04))
285 printk(KERN_DEBUG
"<%s", key
);
287 outb(len
, APPLESMC_DATA_PORT
);
289 printk(KERN_DEBUG
">%x", len
);
291 for (i
= 0; i
< len
; i
++) {
292 if (__wait_status(0x05))
294 buffer
[i
] = inb(APPLESMC_DATA_PORT
);
296 printk(KERN_DEBUG
"<%x", buffer
[i
]);
299 printk(KERN_DEBUG
"\n");
305 * applesmc_write_key - writes len bytes from buffer to a given key.
306 * Returns zero on success or a negative error on failure. Callers must
307 * hold applesmc_lock.
309 static int applesmc_write_key(const char* key
, u8
* buffer
, u8 len
)
313 if (len
> APPLESMC_MAX_DATA_LENGTH
) {
314 printk(KERN_ERR
"applesmc_write_key: cannot write more than "
315 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH
);
319 if (send_command(APPLESMC_WRITE_CMD
))
322 for (i
= 0; i
< 4; i
++) {
323 outb(key
[i
], APPLESMC_DATA_PORT
);
324 if (__wait_status(0x04))
328 outb(len
, APPLESMC_DATA_PORT
);
330 for (i
= 0; i
< len
; i
++) {
331 if (__wait_status(0x04))
333 outb(buffer
[i
], APPLESMC_DATA_PORT
);
340 * applesmc_get_key_at_index - get key at index, and put the result in key
341 * (char[6]). Returns zero on success or a negative error on failure. Callers
342 * must hold applesmc_lock.
344 static int applesmc_get_key_at_index(int index
, char* key
)
348 readkey
[0] = index
>> 24;
349 readkey
[1] = index
>> 16;
350 readkey
[2] = index
>> 8;
353 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD
))
356 for (i
= 0; i
< 4; i
++) {
357 outb(readkey
[i
], APPLESMC_DATA_PORT
);
358 if (__wait_status(0x04))
362 outb(4, APPLESMC_DATA_PORT
);
364 for (i
= 0; i
< 4; i
++) {
365 if (__wait_status(0x05))
367 key
[i
] = inb(APPLESMC_DATA_PORT
);
375 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
376 * Returns zero on success or a negative error on failure. Callers must
377 * hold applesmc_lock.
379 static int applesmc_get_key_type(char* key
, char* type
)
383 if (send_command(APPLESMC_GET_KEY_TYPE_CMD
))
386 for (i
= 0; i
< 4; i
++) {
387 outb(key
[i
], APPLESMC_DATA_PORT
);
388 if (__wait_status(0x04))
392 outb(6, APPLESMC_DATA_PORT
);
394 for (i
= 0; i
< 6; i
++) {
395 if (__wait_status(0x05))
397 type
[i
] = inb(APPLESMC_DATA_PORT
);
405 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
406 * hold applesmc_lock.
408 static int applesmc_read_motion_sensor(int index
, s16
* value
)
415 ret
= applesmc_read_key(MOTION_SENSOR_X_KEY
, buffer
, 2);
418 ret
= applesmc_read_key(MOTION_SENSOR_Y_KEY
, buffer
, 2);
421 ret
= applesmc_read_key(MOTION_SENSOR_Z_KEY
, buffer
, 2);
427 *value
= ((s16
)buffer
[0] << 8) | buffer
[1];
433 * applesmc_device_init - initialize the accelerometer. Returns zero on success
434 * and negative error code on failure. Can sleep.
436 static int applesmc_device_init(void)
438 int total
, ret
= -ENXIO
;
441 if (!applesmc_accelerometer
)
444 mutex_lock(&applesmc_lock
);
446 for (total
= INIT_TIMEOUT_MSECS
; total
> 0; total
-= INIT_WAIT_MSECS
) {
448 printk(KERN_DEBUG
"applesmc try %d\n", total
);
449 if (!applesmc_read_key(MOTION_SENSOR_KEY
, buffer
, 2) &&
450 (buffer
[0] != 0x00 || buffer
[1] != 0x00)) {
451 if (total
== INIT_TIMEOUT_MSECS
) {
452 printk(KERN_DEBUG
"applesmc: device has"
453 " already been initialized"
454 " (0x%02x, 0x%02x).\n",
455 buffer
[0], buffer
[1]);
457 printk(KERN_DEBUG
"applesmc: device"
458 " successfully initialized"
459 " (0x%02x, 0x%02x).\n",
460 buffer
[0], buffer
[1]);
467 applesmc_write_key(MOTION_SENSOR_KEY
, buffer
, 2);
468 msleep(INIT_WAIT_MSECS
);
471 printk(KERN_WARNING
"applesmc: failed to init the device\n");
474 mutex_unlock(&applesmc_lock
);
479 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
482 static int applesmc_get_fan_count(void)
487 mutex_lock(&applesmc_lock
);
489 ret
= applesmc_read_key(FANS_COUNT
, buffer
, 1);
491 mutex_unlock(&applesmc_lock
);
498 /* Device model stuff */
499 static int applesmc_probe(struct platform_device
*dev
)
503 ret
= applesmc_device_init();
507 printk(KERN_INFO
"applesmc: device successfully initialized.\n");
511 /* Synchronize device with memorized backlight state */
512 static int applesmc_pm_resume(struct device
*dev
)
514 mutex_lock(&applesmc_lock
);
516 applesmc_write_key(BACKLIGHT_KEY
, backlight_state
, 2);
517 mutex_unlock(&applesmc_lock
);
521 /* Reinitialize device on resume from hibernation */
522 static int applesmc_pm_restore(struct device
*dev
)
524 int ret
= applesmc_device_init();
527 return applesmc_pm_resume(dev
);
530 static const struct dev_pm_ops applesmc_pm_ops
= {
531 .resume
= applesmc_pm_resume
,
532 .restore
= applesmc_pm_restore
,
535 static struct platform_driver applesmc_driver
= {
536 .probe
= applesmc_probe
,
539 .owner
= THIS_MODULE
,
540 .pm
= &applesmc_pm_ops
,
545 * applesmc_calibrate - Set our "resting" values. Callers must
546 * hold applesmc_lock.
548 static void applesmc_calibrate(void)
550 applesmc_read_motion_sensor(SENSOR_X
, &rest_x
);
551 applesmc_read_motion_sensor(SENSOR_Y
, &rest_y
);
555 static void applesmc_idev_poll(struct input_polled_dev
*dev
)
557 struct input_dev
*idev
= dev
->input
;
560 mutex_lock(&applesmc_lock
);
562 if (applesmc_read_motion_sensor(SENSOR_X
, &x
))
564 if (applesmc_read_motion_sensor(SENSOR_Y
, &y
))
568 input_report_abs(idev
, ABS_X
, x
- rest_x
);
569 input_report_abs(idev
, ABS_Y
, y
- rest_y
);
573 mutex_unlock(&applesmc_lock
);
578 static ssize_t
applesmc_name_show(struct device
*dev
,
579 struct device_attribute
*attr
, char *buf
)
581 return snprintf(buf
, PAGE_SIZE
, "applesmc\n");
584 static ssize_t
applesmc_position_show(struct device
*dev
,
585 struct device_attribute
*attr
, char *buf
)
590 mutex_lock(&applesmc_lock
);
592 ret
= applesmc_read_motion_sensor(SENSOR_X
, &x
);
595 ret
= applesmc_read_motion_sensor(SENSOR_Y
, &y
);
598 ret
= applesmc_read_motion_sensor(SENSOR_Z
, &z
);
603 mutex_unlock(&applesmc_lock
);
607 return snprintf(buf
, PAGE_SIZE
, "(%d,%d,%d)\n", x
, y
, z
);
610 static ssize_t
applesmc_light_show(struct device
*dev
,
611 struct device_attribute
*attr
, char *sysfsbuf
)
613 static int data_length
;
615 u8 left
= 0, right
= 0;
616 u8 buffer
[10], query
[6];
618 mutex_lock(&applesmc_lock
);
621 ret
= applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY
, query
);
624 data_length
= clamp_val(query
[0], 0, 10);
625 printk(KERN_INFO
"applesmc: light sensor data length set to "
626 "%d\n", data_length
);
629 ret
= applesmc_read_key(LIGHT_SENSOR_LEFT_KEY
, buffer
, data_length
);
630 /* newer macbooks report a single 10-bit bigendian value */
631 if (data_length
== 10) {
632 left
= be16_to_cpu(*(__be16
*)(buffer
+ 6)) >> 2;
638 ret
= applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY
, buffer
, data_length
);
642 mutex_unlock(&applesmc_lock
);
646 return snprintf(sysfsbuf
, PAGE_SIZE
, "(%d,%d)\n", left
, right
);
649 /* Displays degree Celsius * 1000 */
650 static ssize_t
applesmc_show_temperature(struct device
*dev
,
651 struct device_attribute
*devattr
, char *sysfsbuf
)
656 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
658 temperature_sensors_sets
[applesmc_temperature_set
][attr
->index
];
660 mutex_lock(&applesmc_lock
);
662 ret
= applesmc_read_key(key
, buffer
, 2);
663 temp
= buffer
[0]*1000;
664 temp
+= (buffer
[1] >> 6) * 250;
666 mutex_unlock(&applesmc_lock
);
671 return snprintf(sysfsbuf
, PAGE_SIZE
, "%u\n", temp
);
674 static ssize_t
applesmc_show_fan_speed(struct device
*dev
,
675 struct device_attribute
*attr
, char *sysfsbuf
)
678 unsigned int speed
= 0;
681 struct sensor_device_attribute_2
*sensor_attr
=
682 to_sensor_dev_attr_2(attr
);
684 newkey
[0] = fan_speed_keys
[sensor_attr
->nr
][0];
685 newkey
[1] = '0' + sensor_attr
->index
;
686 newkey
[2] = fan_speed_keys
[sensor_attr
->nr
][2];
687 newkey
[3] = fan_speed_keys
[sensor_attr
->nr
][3];
690 mutex_lock(&applesmc_lock
);
692 ret
= applesmc_read_key(newkey
, buffer
, 2);
693 speed
= ((buffer
[0] << 8 | buffer
[1]) >> 2);
695 mutex_unlock(&applesmc_lock
);
699 return snprintf(sysfsbuf
, PAGE_SIZE
, "%u\n", speed
);
702 static ssize_t
applesmc_store_fan_speed(struct device
*dev
,
703 struct device_attribute
*attr
,
704 const char *sysfsbuf
, size_t count
)
710 struct sensor_device_attribute_2
*sensor_attr
=
711 to_sensor_dev_attr_2(attr
);
713 speed
= simple_strtoul(sysfsbuf
, NULL
, 10);
715 if (speed
> 0x4000) /* Bigger than a 14-bit value */
718 newkey
[0] = fan_speed_keys
[sensor_attr
->nr
][0];
719 newkey
[1] = '0' + sensor_attr
->index
;
720 newkey
[2] = fan_speed_keys
[sensor_attr
->nr
][2];
721 newkey
[3] = fan_speed_keys
[sensor_attr
->nr
][3];
724 mutex_lock(&applesmc_lock
);
726 buffer
[0] = (speed
>> 6) & 0xff;
727 buffer
[1] = (speed
<< 2) & 0xff;
728 ret
= applesmc_write_key(newkey
, buffer
, 2);
730 mutex_unlock(&applesmc_lock
);
737 static ssize_t
applesmc_show_fan_manual(struct device
*dev
,
738 struct device_attribute
*devattr
, char *sysfsbuf
)
743 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
745 mutex_lock(&applesmc_lock
);
747 ret
= applesmc_read_key(FANS_MANUAL
, buffer
, 2);
748 manual
= ((buffer
[0] << 8 | buffer
[1]) >> attr
->index
) & 0x01;
750 mutex_unlock(&applesmc_lock
);
754 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", manual
);
757 static ssize_t
applesmc_store_fan_manual(struct device
*dev
,
758 struct device_attribute
*devattr
,
759 const char *sysfsbuf
, size_t count
)
765 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
767 input
= simple_strtoul(sysfsbuf
, NULL
, 10);
769 mutex_lock(&applesmc_lock
);
771 ret
= applesmc_read_key(FANS_MANUAL
, buffer
, 2);
772 val
= (buffer
[0] << 8 | buffer
[1]);
777 val
= val
| (0x01 << attr
->index
);
779 val
= val
& ~(0x01 << attr
->index
);
781 buffer
[0] = (val
>> 8) & 0xFF;
782 buffer
[1] = val
& 0xFF;
784 ret
= applesmc_write_key(FANS_MANUAL
, buffer
, 2);
787 mutex_unlock(&applesmc_lock
);
794 static ssize_t
applesmc_show_fan_position(struct device
*dev
,
795 struct device_attribute
*attr
, char *sysfsbuf
)
800 struct sensor_device_attribute_2
*sensor_attr
=
801 to_sensor_dev_attr_2(attr
);
803 newkey
[0] = FAN_POSITION
[0];
804 newkey
[1] = '0' + sensor_attr
->index
;
805 newkey
[2] = FAN_POSITION
[2];
806 newkey
[3] = FAN_POSITION
[3];
809 mutex_lock(&applesmc_lock
);
811 ret
= applesmc_read_key(newkey
, buffer
, 16);
814 mutex_unlock(&applesmc_lock
);
818 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", buffer
+4);
821 static ssize_t
applesmc_calibrate_show(struct device
*dev
,
822 struct device_attribute
*attr
, char *sysfsbuf
)
824 return snprintf(sysfsbuf
, PAGE_SIZE
, "(%d,%d)\n", rest_x
, rest_y
);
827 static ssize_t
applesmc_calibrate_store(struct device
*dev
,
828 struct device_attribute
*attr
, const char *sysfsbuf
, size_t count
)
830 mutex_lock(&applesmc_lock
);
831 applesmc_calibrate();
832 mutex_unlock(&applesmc_lock
);
837 static void applesmc_backlight_set(struct work_struct
*work
)
839 mutex_lock(&applesmc_lock
);
840 applesmc_write_key(BACKLIGHT_KEY
, backlight_state
, 2);
841 mutex_unlock(&applesmc_lock
);
843 static DECLARE_WORK(backlight_work
, &applesmc_backlight_set
);
845 static void applesmc_brightness_set(struct led_classdev
*led_cdev
,
846 enum led_brightness value
)
850 backlight_state
[0] = value
;
851 ret
= queue_work(applesmc_led_wq
, &backlight_work
);
854 printk(KERN_DEBUG
"applesmc: work was already on the queue.\n");
857 static ssize_t
applesmc_key_count_show(struct device
*dev
,
858 struct device_attribute
*attr
, char *sysfsbuf
)
864 mutex_lock(&applesmc_lock
);
866 ret
= applesmc_read_key(KEY_COUNT_KEY
, buffer
, 4);
867 count
= ((u32
)buffer
[0]<<24) + ((u32
)buffer
[1]<<16) +
868 ((u32
)buffer
[2]<<8) + buffer
[3];
870 mutex_unlock(&applesmc_lock
);
874 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", count
);
877 static ssize_t
applesmc_key_at_index_read_show(struct device
*dev
,
878 struct device_attribute
*attr
, char *sysfsbuf
)
884 mutex_lock(&applesmc_lock
);
886 ret
= applesmc_get_key_at_index(key_at_index
, key
);
888 if (ret
|| !key
[0]) {
889 mutex_unlock(&applesmc_lock
);
894 ret
= applesmc_get_key_type(key
, info
);
897 mutex_unlock(&applesmc_lock
);
903 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
904 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
906 ret
= applesmc_read_key(key
, sysfsbuf
, info
[0]);
908 mutex_unlock(&applesmc_lock
);
917 static ssize_t
applesmc_key_at_index_data_length_show(struct device
*dev
,
918 struct device_attribute
*attr
, char *sysfsbuf
)
924 mutex_lock(&applesmc_lock
);
926 ret
= applesmc_get_key_at_index(key_at_index
, key
);
928 if (ret
|| !key
[0]) {
929 mutex_unlock(&applesmc_lock
);
934 ret
= applesmc_get_key_type(key
, info
);
936 mutex_unlock(&applesmc_lock
);
939 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", info
[0]);
944 static ssize_t
applesmc_key_at_index_type_show(struct device
*dev
,
945 struct device_attribute
*attr
, char *sysfsbuf
)
951 mutex_lock(&applesmc_lock
);
953 ret
= applesmc_get_key_at_index(key_at_index
, key
);
955 if (ret
|| !key
[0]) {
956 mutex_unlock(&applesmc_lock
);
961 ret
= applesmc_get_key_type(key
, info
);
963 mutex_unlock(&applesmc_lock
);
966 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", info
+1);
971 static ssize_t
applesmc_key_at_index_name_show(struct device
*dev
,
972 struct device_attribute
*attr
, char *sysfsbuf
)
977 mutex_lock(&applesmc_lock
);
979 ret
= applesmc_get_key_at_index(key_at_index
, key
);
981 mutex_unlock(&applesmc_lock
);
984 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", key
);
989 static ssize_t
applesmc_key_at_index_show(struct device
*dev
,
990 struct device_attribute
*attr
, char *sysfsbuf
)
992 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", key_at_index
);
995 static ssize_t
applesmc_key_at_index_store(struct device
*dev
,
996 struct device_attribute
*attr
, const char *sysfsbuf
, size_t count
)
998 mutex_lock(&applesmc_lock
);
1000 key_at_index
= simple_strtoul(sysfsbuf
, NULL
, 10);
1002 mutex_unlock(&applesmc_lock
);
1007 static struct led_classdev applesmc_backlight
= {
1008 .name
= "smc::kbd_backlight",
1009 .default_trigger
= "nand-disk",
1010 .brightness_set
= applesmc_brightness_set
,
1013 static DEVICE_ATTR(name
, 0444, applesmc_name_show
, NULL
);
1015 static DEVICE_ATTR(position
, 0444, applesmc_position_show
, NULL
);
1016 static DEVICE_ATTR(calibrate
, 0644,
1017 applesmc_calibrate_show
, applesmc_calibrate_store
);
1019 static struct attribute
*accelerometer_attributes
[] = {
1020 &dev_attr_position
.attr
,
1021 &dev_attr_calibrate
.attr
,
1025 static const struct attribute_group accelerometer_attributes_group
=
1026 { .attrs
= accelerometer_attributes
};
1028 static DEVICE_ATTR(light
, 0444, applesmc_light_show
, NULL
);
1030 static DEVICE_ATTR(key_count
, 0444, applesmc_key_count_show
, NULL
);
1031 static DEVICE_ATTR(key_at_index
, 0644,
1032 applesmc_key_at_index_show
, applesmc_key_at_index_store
);
1033 static DEVICE_ATTR(key_at_index_name
, 0444,
1034 applesmc_key_at_index_name_show
, NULL
);
1035 static DEVICE_ATTR(key_at_index_type
, 0444,
1036 applesmc_key_at_index_type_show
, NULL
);
1037 static DEVICE_ATTR(key_at_index_data_length
, 0444,
1038 applesmc_key_at_index_data_length_show
, NULL
);
1039 static DEVICE_ATTR(key_at_index_data
, 0444,
1040 applesmc_key_at_index_read_show
, NULL
);
1042 static struct attribute
*key_enumeration_attributes
[] = {
1043 &dev_attr_key_count
.attr
,
1044 &dev_attr_key_at_index
.attr
,
1045 &dev_attr_key_at_index_name
.attr
,
1046 &dev_attr_key_at_index_type
.attr
,
1047 &dev_attr_key_at_index_data_length
.attr
,
1048 &dev_attr_key_at_index_data
.attr
,
1052 static const struct attribute_group key_enumeration_group
=
1053 { .attrs
= key_enumeration_attributes
};
1056 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1057 * - show actual speed
1058 * - show/store minimum speed
1059 * - show maximum speed
1061 * - show/store target speed
1062 * - show/store manual mode
1064 #define sysfs_fan_speeds_offset(offset) \
1065 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1066 applesmc_show_fan_speed, NULL, 0, offset-1); \
1068 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1069 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1071 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1072 applesmc_show_fan_speed, NULL, 2, offset-1); \
1074 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1075 applesmc_show_fan_speed, NULL, 3, offset-1); \
1077 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1078 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1080 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1081 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1083 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1084 applesmc_show_fan_position, NULL, offset-1); \
1086 static struct attribute *fan##offset##_attributes[] = { \
1087 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1088 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1089 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1090 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1091 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1092 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1093 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1098 * Create the needed functions for each fan using the macro defined above
1099 * (4 fans are supported)
1101 sysfs_fan_speeds_offset(1);
1102 sysfs_fan_speeds_offset(2);
1103 sysfs_fan_speeds_offset(3);
1104 sysfs_fan_speeds_offset(4);
1106 static const struct attribute_group fan_attribute_groups
[] = {
1107 { .attrs
= fan1_attributes
},
1108 { .attrs
= fan2_attributes
},
1109 { .attrs
= fan3_attributes
},
1110 { .attrs
= fan4_attributes
},
1114 * Temperature sensors sysfs entries.
1116 static SENSOR_DEVICE_ATTR(temp1_input
, S_IRUGO
,
1117 applesmc_show_temperature
, NULL
, 0);
1118 static SENSOR_DEVICE_ATTR(temp2_input
, S_IRUGO
,
1119 applesmc_show_temperature
, NULL
, 1);
1120 static SENSOR_DEVICE_ATTR(temp3_input
, S_IRUGO
,
1121 applesmc_show_temperature
, NULL
, 2);
1122 static SENSOR_DEVICE_ATTR(temp4_input
, S_IRUGO
,
1123 applesmc_show_temperature
, NULL
, 3);
1124 static SENSOR_DEVICE_ATTR(temp5_input
, S_IRUGO
,
1125 applesmc_show_temperature
, NULL
, 4);
1126 static SENSOR_DEVICE_ATTR(temp6_input
, S_IRUGO
,
1127 applesmc_show_temperature
, NULL
, 5);
1128 static SENSOR_DEVICE_ATTR(temp7_input
, S_IRUGO
,
1129 applesmc_show_temperature
, NULL
, 6);
1130 static SENSOR_DEVICE_ATTR(temp8_input
, S_IRUGO
,
1131 applesmc_show_temperature
, NULL
, 7);
1132 static SENSOR_DEVICE_ATTR(temp9_input
, S_IRUGO
,
1133 applesmc_show_temperature
, NULL
, 8);
1134 static SENSOR_DEVICE_ATTR(temp10_input
, S_IRUGO
,
1135 applesmc_show_temperature
, NULL
, 9);
1136 static SENSOR_DEVICE_ATTR(temp11_input
, S_IRUGO
,
1137 applesmc_show_temperature
, NULL
, 10);
1138 static SENSOR_DEVICE_ATTR(temp12_input
, S_IRUGO
,
1139 applesmc_show_temperature
, NULL
, 11);
1140 static SENSOR_DEVICE_ATTR(temp13_input
, S_IRUGO
,
1141 applesmc_show_temperature
, NULL
, 12);
1142 static SENSOR_DEVICE_ATTR(temp14_input
, S_IRUGO
,
1143 applesmc_show_temperature
, NULL
, 13);
1144 static SENSOR_DEVICE_ATTR(temp15_input
, S_IRUGO
,
1145 applesmc_show_temperature
, NULL
, 14);
1146 static SENSOR_DEVICE_ATTR(temp16_input
, S_IRUGO
,
1147 applesmc_show_temperature
, NULL
, 15);
1148 static SENSOR_DEVICE_ATTR(temp17_input
, S_IRUGO
,
1149 applesmc_show_temperature
, NULL
, 16);
1150 static SENSOR_DEVICE_ATTR(temp18_input
, S_IRUGO
,
1151 applesmc_show_temperature
, NULL
, 17);
1152 static SENSOR_DEVICE_ATTR(temp19_input
, S_IRUGO
,
1153 applesmc_show_temperature
, NULL
, 18);
1154 static SENSOR_DEVICE_ATTR(temp20_input
, S_IRUGO
,
1155 applesmc_show_temperature
, NULL
, 19);
1156 static SENSOR_DEVICE_ATTR(temp21_input
, S_IRUGO
,
1157 applesmc_show_temperature
, NULL
, 20);
1158 static SENSOR_DEVICE_ATTR(temp22_input
, S_IRUGO
,
1159 applesmc_show_temperature
, NULL
, 21);
1160 static SENSOR_DEVICE_ATTR(temp23_input
, S_IRUGO
,
1161 applesmc_show_temperature
, NULL
, 22);
1162 static SENSOR_DEVICE_ATTR(temp24_input
, S_IRUGO
,
1163 applesmc_show_temperature
, NULL
, 23);
1164 static SENSOR_DEVICE_ATTR(temp25_input
, S_IRUGO
,
1165 applesmc_show_temperature
, NULL
, 24);
1166 static SENSOR_DEVICE_ATTR(temp26_input
, S_IRUGO
,
1167 applesmc_show_temperature
, NULL
, 25);
1168 static SENSOR_DEVICE_ATTR(temp27_input
, S_IRUGO
,
1169 applesmc_show_temperature
, NULL
, 26);
1170 static SENSOR_DEVICE_ATTR(temp28_input
, S_IRUGO
,
1171 applesmc_show_temperature
, NULL
, 27);
1172 static SENSOR_DEVICE_ATTR(temp29_input
, S_IRUGO
,
1173 applesmc_show_temperature
, NULL
, 28);
1174 static SENSOR_DEVICE_ATTR(temp30_input
, S_IRUGO
,
1175 applesmc_show_temperature
, NULL
, 29);
1176 static SENSOR_DEVICE_ATTR(temp31_input
, S_IRUGO
,
1177 applesmc_show_temperature
, NULL
, 30);
1178 static SENSOR_DEVICE_ATTR(temp32_input
, S_IRUGO
,
1179 applesmc_show_temperature
, NULL
, 31);
1180 static SENSOR_DEVICE_ATTR(temp33_input
, S_IRUGO
,
1181 applesmc_show_temperature
, NULL
, 32);
1182 static SENSOR_DEVICE_ATTR(temp34_input
, S_IRUGO
,
1183 applesmc_show_temperature
, NULL
, 33);
1184 static SENSOR_DEVICE_ATTR(temp35_input
, S_IRUGO
,
1185 applesmc_show_temperature
, NULL
, 34);
1186 static SENSOR_DEVICE_ATTR(temp36_input
, S_IRUGO
,
1187 applesmc_show_temperature
, NULL
, 35);
1188 static SENSOR_DEVICE_ATTR(temp37_input
, S_IRUGO
,
1189 applesmc_show_temperature
, NULL
, 36);
1190 static SENSOR_DEVICE_ATTR(temp38_input
, S_IRUGO
,
1191 applesmc_show_temperature
, NULL
, 37);
1192 static SENSOR_DEVICE_ATTR(temp39_input
, S_IRUGO
,
1193 applesmc_show_temperature
, NULL
, 38);
1194 static SENSOR_DEVICE_ATTR(temp40_input
, S_IRUGO
,
1195 applesmc_show_temperature
, NULL
, 39);
1197 static struct attribute
*temperature_attributes
[] = {
1198 &sensor_dev_attr_temp1_input
.dev_attr
.attr
,
1199 &sensor_dev_attr_temp2_input
.dev_attr
.attr
,
1200 &sensor_dev_attr_temp3_input
.dev_attr
.attr
,
1201 &sensor_dev_attr_temp4_input
.dev_attr
.attr
,
1202 &sensor_dev_attr_temp5_input
.dev_attr
.attr
,
1203 &sensor_dev_attr_temp6_input
.dev_attr
.attr
,
1204 &sensor_dev_attr_temp7_input
.dev_attr
.attr
,
1205 &sensor_dev_attr_temp8_input
.dev_attr
.attr
,
1206 &sensor_dev_attr_temp9_input
.dev_attr
.attr
,
1207 &sensor_dev_attr_temp10_input
.dev_attr
.attr
,
1208 &sensor_dev_attr_temp11_input
.dev_attr
.attr
,
1209 &sensor_dev_attr_temp12_input
.dev_attr
.attr
,
1210 &sensor_dev_attr_temp13_input
.dev_attr
.attr
,
1211 &sensor_dev_attr_temp14_input
.dev_attr
.attr
,
1212 &sensor_dev_attr_temp15_input
.dev_attr
.attr
,
1213 &sensor_dev_attr_temp16_input
.dev_attr
.attr
,
1214 &sensor_dev_attr_temp17_input
.dev_attr
.attr
,
1215 &sensor_dev_attr_temp18_input
.dev_attr
.attr
,
1216 &sensor_dev_attr_temp19_input
.dev_attr
.attr
,
1217 &sensor_dev_attr_temp20_input
.dev_attr
.attr
,
1218 &sensor_dev_attr_temp21_input
.dev_attr
.attr
,
1219 &sensor_dev_attr_temp22_input
.dev_attr
.attr
,
1220 &sensor_dev_attr_temp23_input
.dev_attr
.attr
,
1221 &sensor_dev_attr_temp24_input
.dev_attr
.attr
,
1222 &sensor_dev_attr_temp25_input
.dev_attr
.attr
,
1223 &sensor_dev_attr_temp26_input
.dev_attr
.attr
,
1224 &sensor_dev_attr_temp27_input
.dev_attr
.attr
,
1225 &sensor_dev_attr_temp28_input
.dev_attr
.attr
,
1226 &sensor_dev_attr_temp29_input
.dev_attr
.attr
,
1227 &sensor_dev_attr_temp30_input
.dev_attr
.attr
,
1228 &sensor_dev_attr_temp31_input
.dev_attr
.attr
,
1229 &sensor_dev_attr_temp32_input
.dev_attr
.attr
,
1230 &sensor_dev_attr_temp33_input
.dev_attr
.attr
,
1231 &sensor_dev_attr_temp34_input
.dev_attr
.attr
,
1232 &sensor_dev_attr_temp35_input
.dev_attr
.attr
,
1233 &sensor_dev_attr_temp36_input
.dev_attr
.attr
,
1234 &sensor_dev_attr_temp37_input
.dev_attr
.attr
,
1235 &sensor_dev_attr_temp38_input
.dev_attr
.attr
,
1236 &sensor_dev_attr_temp39_input
.dev_attr
.attr
,
1237 &sensor_dev_attr_temp40_input
.dev_attr
.attr
,
1241 static const struct attribute_group temperature_attributes_group
=
1242 { .attrs
= temperature_attributes
};
1247 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1249 static int applesmc_dmi_match(const struct dmi_system_id
*id
)
1252 struct dmi_match_data
* dmi_data
= id
->driver_data
;
1253 printk(KERN_INFO
"applesmc: %s detected:\n", id
->ident
);
1254 applesmc_accelerometer
= dmi_data
->accelerometer
;
1255 printk(KERN_INFO
"applesmc: - Model %s accelerometer\n",
1256 applesmc_accelerometer
? "with" : "without");
1257 applesmc_light
= dmi_data
->light
;
1258 printk(KERN_INFO
"applesmc: - Model %s light sensors and backlight\n",
1259 applesmc_light
? "with" : "without");
1261 applesmc_temperature_set
= dmi_data
->temperature_set
;
1262 while (temperature_sensors_sets
[applesmc_temperature_set
][i
] != NULL
)
1264 printk(KERN_INFO
"applesmc: - Model with %d temperature sensors\n", i
);
1268 /* Create accelerometer ressources */
1269 static int applesmc_create_accelerometer(void)
1271 struct input_dev
*idev
;
1274 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1275 &accelerometer_attributes_group
);
1279 applesmc_idev
= input_allocate_polled_device();
1280 if (!applesmc_idev
) {
1285 applesmc_idev
->poll
= applesmc_idev_poll
;
1286 applesmc_idev
->poll_interval
= APPLESMC_POLL_INTERVAL
;
1288 /* initial calibrate for the input device */
1289 applesmc_calibrate();
1291 /* initialize the input device */
1292 idev
= applesmc_idev
->input
;
1293 idev
->name
= "applesmc";
1294 idev
->id
.bustype
= BUS_HOST
;
1295 idev
->dev
.parent
= &pdev
->dev
;
1296 idev
->evbit
[0] = BIT_MASK(EV_ABS
);
1297 input_set_abs_params(idev
, ABS_X
,
1298 -256, 256, APPLESMC_INPUT_FUZZ
, APPLESMC_INPUT_FLAT
);
1299 input_set_abs_params(idev
, ABS_Y
,
1300 -256, 256, APPLESMC_INPUT_FUZZ
, APPLESMC_INPUT_FLAT
);
1302 ret
= input_register_polled_device(applesmc_idev
);
1309 input_free_polled_device(applesmc_idev
);
1312 sysfs_remove_group(&pdev
->dev
.kobj
, &accelerometer_attributes_group
);
1315 printk(KERN_WARNING
"applesmc: driver init failed (ret=%d)!\n", ret
);
1319 /* Release all ressources used by the accelerometer */
1320 static void applesmc_release_accelerometer(void)
1322 input_unregister_polled_device(applesmc_idev
);
1323 input_free_polled_device(applesmc_idev
);
1324 sysfs_remove_group(&pdev
->dev
.kobj
, &accelerometer_attributes_group
);
1327 static __initdata
struct dmi_match_data applesmc_dmi_data
[] = {
1328 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1329 { .accelerometer
= 1, .light
= 1, .temperature_set
= 0 },
1330 /* MacBook2: accelerometer and temperature set 1 */
1331 { .accelerometer
= 1, .light
= 0, .temperature_set
= 1 },
1332 /* MacBook: accelerometer and temperature set 2 */
1333 { .accelerometer
= 1, .light
= 0, .temperature_set
= 2 },
1334 /* MacMini: temperature set 3 */
1335 { .accelerometer
= 0, .light
= 0, .temperature_set
= 3 },
1336 /* MacPro: temperature set 4 */
1337 { .accelerometer
= 0, .light
= 0, .temperature_set
= 4 },
1338 /* iMac: temperature set 5 */
1339 { .accelerometer
= 0, .light
= 0, .temperature_set
= 5 },
1340 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1341 { .accelerometer
= 1, .light
= 0, .temperature_set
= 6 },
1342 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1343 { .accelerometer
= 1, .light
= 1, .temperature_set
= 7 },
1344 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1345 { .accelerometer
= 1, .light
= 1, .temperature_set
= 8 },
1346 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1347 { .accelerometer
= 1, .light
= 1, .temperature_set
= 9 },
1348 /* iMac 5: light sensor only, temperature set 10 */
1349 { .accelerometer
= 0, .light
= 0, .temperature_set
= 10 },
1350 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1351 { .accelerometer
= 1, .light
= 1, .temperature_set
= 11 },
1352 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1353 { .accelerometer
= 1, .light
= 1, .temperature_set
= 12 },
1354 /* iMac 8: light sensor only, temperature set 13 */
1355 { .accelerometer
= 0, .light
= 0, .temperature_set
= 13 },
1356 /* iMac 6: light sensor only, temperature set 14 */
1357 { .accelerometer
= 0, .light
= 0, .temperature_set
= 14 },
1358 /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
1359 { .accelerometer
= 1, .light
= 1, .temperature_set
= 15 },
1360 /* MacPro3,1: temperature set 16 */
1361 { .accelerometer
= 0, .light
= 0, .temperature_set
= 16 },
1362 /* iMac 9,1: light sensor only, temperature set 17 */
1363 { .accelerometer
= 0, .light
= 0, .temperature_set
= 17 },
1364 /* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
1365 { .accelerometer
= 1, .light
= 1, .temperature_set
= 18 },
1368 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1369 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1370 static __initdata
struct dmi_system_id applesmc_whitelist
[] = {
1371 { applesmc_dmi_match
, "Apple MacBook Air 2", {
1372 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1373 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookAir2") },
1374 &applesmc_dmi_data
[15]},
1375 { applesmc_dmi_match
, "Apple MacBook Air", {
1376 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1377 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookAir") },
1378 &applesmc_dmi_data
[7]},
1379 { applesmc_dmi_match
, "Apple MacBook Pro 5", {
1380 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1381 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro5") },
1382 &applesmc_dmi_data
[12]},
1383 { applesmc_dmi_match
, "Apple MacBook Pro 4", {
1384 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1385 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro4") },
1386 &applesmc_dmi_data
[8]},
1387 { applesmc_dmi_match
, "Apple MacBook Pro 3", {
1388 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1389 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro3") },
1390 &applesmc_dmi_data
[9]},
1391 { applesmc_dmi_match
, "Apple MacBook Pro 2,2", {
1392 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple Computer, Inc."),
1393 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro2,2") },
1394 &applesmc_dmi_data
[18]},
1395 { applesmc_dmi_match
, "Apple MacBook Pro", {
1396 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1397 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBookPro") },
1398 &applesmc_dmi_data
[0]},
1399 { applesmc_dmi_match
, "Apple MacBook (v2)", {
1400 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1401 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook2") },
1402 &applesmc_dmi_data
[1]},
1403 { applesmc_dmi_match
, "Apple MacBook (v3)", {
1404 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1405 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook3") },
1406 &applesmc_dmi_data
[6]},
1407 { applesmc_dmi_match
, "Apple MacBook 4", {
1408 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1409 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBook4") },
1410 &applesmc_dmi_data
[6]},
1411 { applesmc_dmi_match
, "Apple MacBook 5", {
1412 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1413 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBook5") },
1414 &applesmc_dmi_data
[11]},
1415 { applesmc_dmi_match
, "Apple MacBook", {
1416 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1417 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook") },
1418 &applesmc_dmi_data
[2]},
1419 { applesmc_dmi_match
, "Apple Macmini", {
1420 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1421 DMI_MATCH(DMI_PRODUCT_NAME
,"Macmini") },
1422 &applesmc_dmi_data
[3]},
1423 { applesmc_dmi_match
, "Apple MacPro2", {
1424 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1425 DMI_MATCH(DMI_PRODUCT_NAME
,"MacPro2") },
1426 &applesmc_dmi_data
[4]},
1427 { applesmc_dmi_match
, "Apple MacPro3", {
1428 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1429 DMI_MATCH(DMI_PRODUCT_NAME
, "MacPro3") },
1430 &applesmc_dmi_data
[16]},
1431 { applesmc_dmi_match
, "Apple MacPro", {
1432 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1433 DMI_MATCH(DMI_PRODUCT_NAME
, "MacPro") },
1434 &applesmc_dmi_data
[4]},
1435 { applesmc_dmi_match
, "Apple iMac 9,1", {
1436 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple Inc."),
1437 DMI_MATCH(DMI_PRODUCT_NAME
, "iMac9,1") },
1438 &applesmc_dmi_data
[17]},
1439 { applesmc_dmi_match
, "Apple iMac 8", {
1440 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1441 DMI_MATCH(DMI_PRODUCT_NAME
, "iMac8") },
1442 &applesmc_dmi_data
[13]},
1443 { applesmc_dmi_match
, "Apple iMac 6", {
1444 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1445 DMI_MATCH(DMI_PRODUCT_NAME
, "iMac6") },
1446 &applesmc_dmi_data
[14]},
1447 { applesmc_dmi_match
, "Apple iMac 5", {
1448 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1449 DMI_MATCH(DMI_PRODUCT_NAME
, "iMac5") },
1450 &applesmc_dmi_data
[10]},
1451 { applesmc_dmi_match
, "Apple iMac", {
1452 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1453 DMI_MATCH(DMI_PRODUCT_NAME
,"iMac") },
1454 &applesmc_dmi_data
[5]},
1458 static int __init
applesmc_init(void)
1464 if (!dmi_check_system(applesmc_whitelist
)) {
1465 printk(KERN_WARNING
"applesmc: supported laptop not found!\n");
1470 if (!request_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
,
1476 ret
= platform_driver_register(&applesmc_driver
);
1480 pdev
= platform_device_register_simple("applesmc", APPLESMC_DATA_PORT
,
1483 ret
= PTR_ERR(pdev
);
1487 ret
= sysfs_create_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1491 /* Create key enumeration sysfs files */
1492 ret
= sysfs_create_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1496 /* create fan files */
1497 count
= applesmc_get_fan_count();
1499 printk(KERN_ERR
"applesmc: Cannot get the number of fans.\n");
1501 printk(KERN_INFO
"applesmc: %d fans found.\n", count
);
1505 printk(KERN_WARNING
"applesmc: More than 4 fans found,"
1506 " but at most 4 fans are supported"
1507 " by the driver.\n");
1510 while (fans_handled
< count
) {
1511 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1512 &fan_attribute_groups
[fans_handled
]);
1519 temperature_sensors_sets
[applesmc_temperature_set
][i
] != NULL
;
1521 if (temperature_attributes
[i
] == NULL
) {
1522 printk(KERN_ERR
"applesmc: More temperature sensors "
1523 "in temperature_sensors_sets (at least %i)"
1524 "than available sysfs files in "
1525 "temperature_attributes (%i), please report "
1526 "this bug.\n", i
, i
-1);
1527 goto out_temperature
;
1529 ret
= sysfs_create_file(&pdev
->dev
.kobj
,
1530 temperature_attributes
[i
]);
1532 goto out_temperature
;
1535 if (applesmc_accelerometer
) {
1536 ret
= applesmc_create_accelerometer();
1538 goto out_temperature
;
1541 if (applesmc_light
) {
1542 /* Add light sensor file */
1543 ret
= sysfs_create_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1545 goto out_accelerometer
;
1547 /* Create the workqueue */
1548 applesmc_led_wq
= create_singlethread_workqueue("applesmc-led");
1549 if (!applesmc_led_wq
) {
1551 goto out_light_sysfs
;
1554 /* register as a led device */
1555 ret
= led_classdev_register(&pdev
->dev
, &applesmc_backlight
);
1560 hwmon_dev
= hwmon_device_register(&pdev
->dev
);
1561 if (IS_ERR(hwmon_dev
)) {
1562 ret
= PTR_ERR(hwmon_dev
);
1563 goto out_light_ledclass
;
1566 printk(KERN_INFO
"applesmc: driver successfully loaded.\n");
1572 led_classdev_unregister(&applesmc_backlight
);
1575 destroy_workqueue(applesmc_led_wq
);
1578 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1580 if (applesmc_accelerometer
)
1581 applesmc_release_accelerometer();
1583 sysfs_remove_group(&pdev
->dev
.kobj
, &temperature_attributes_group
);
1585 while (fans_handled
)
1586 sysfs_remove_group(&pdev
->dev
.kobj
,
1587 &fan_attribute_groups
[--fans_handled
]);
1588 sysfs_remove_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1590 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1592 platform_device_unregister(pdev
);
1594 platform_driver_unregister(&applesmc_driver
);
1596 release_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
);
1598 printk(KERN_WARNING
"applesmc: driver init failed (ret=%d)!\n", ret
);
1602 static void __exit
applesmc_exit(void)
1604 hwmon_device_unregister(hwmon_dev
);
1605 if (applesmc_light
) {
1606 led_classdev_unregister(&applesmc_backlight
);
1607 destroy_workqueue(applesmc_led_wq
);
1608 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1610 if (applesmc_accelerometer
)
1611 applesmc_release_accelerometer();
1612 sysfs_remove_group(&pdev
->dev
.kobj
, &temperature_attributes_group
);
1613 while (fans_handled
)
1614 sysfs_remove_group(&pdev
->dev
.kobj
,
1615 &fan_attribute_groups
[--fans_handled
]);
1616 sysfs_remove_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1617 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1618 platform_device_unregister(pdev
);
1619 platform_driver_unregister(&applesmc_driver
);
1620 release_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
);
1622 printk(KERN_INFO
"applesmc: driver unloaded.\n");
1625 module_init(applesmc_init
);
1626 module_exit(applesmc_exit
);
1628 MODULE_AUTHOR("Nicolas Boichat");
1629 MODULE_DESCRIPTION("Apple SMC");
1630 MODULE_LICENSE("GPL v2");
1631 MODULE_DEVICE_TABLE(dmi
, applesmc_whitelist
);