thinkpad-acpi: support the second fan on the X61
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / hwmon / applesmc.c
blob086c2a5cef0bcdfeae7de4cf4fba665b6745134d
1 /*
2 * drivers/hwmon/applesmc.c - driver for Apple's SMC (accelerometer, temperature
3 * sensors, fan control, keyboard backlight control) used in Intel-based Apple
4 * computers.
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
22 * more details.
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>
38 #include <asm/io.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[][36] = {
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 },
104 /* Set 5: iMac */
105 { "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P",
106 "Tp0C", NULL },
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 },
136 /* List of keys used to read/write fan speeds */
137 static const char* fan_speed_keys[] = {
138 FAN_ACTUAL_SPEED,
139 FAN_MIN_SPEED,
140 FAN_MAX_SPEED,
141 FAN_SAFE_SPEED,
142 FAN_TARGET_SPEED
145 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
146 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
148 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
149 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
150 #define APPLESMC_INPUT_FLAT 4
152 #define SENSOR_X 0
153 #define SENSOR_Y 1
154 #define SENSOR_Z 2
156 /* Structure to be passed to DMI_MATCH function */
157 struct dmi_match_data {
158 /* Indicates whether this computer has an accelerometer. */
159 int accelerometer;
160 /* Indicates whether this computer has light sensors and keyboard backlight. */
161 int light;
162 /* Indicates which temperature sensors set to use. */
163 int temperature_set;
166 static const int debug;
167 static struct platform_device *pdev;
168 static s16 rest_x;
169 static s16 rest_y;
170 static struct device *hwmon_dev;
171 static struct input_polled_dev *applesmc_idev;
173 /* Indicates whether this computer has an accelerometer. */
174 static unsigned int applesmc_accelerometer;
176 /* Indicates whether this computer has light sensors and keyboard backlight. */
177 static unsigned int applesmc_light;
179 /* Indicates which temperature sensors set to use. */
180 static unsigned int applesmc_temperature_set;
182 static DEFINE_MUTEX(applesmc_lock);
185 * Last index written to key_at_index sysfs file, and value to use for all other
186 * key_at_index_* sysfs files.
188 static unsigned int key_at_index;
190 static struct workqueue_struct *applesmc_led_wq;
193 * __wait_status - Wait up to 32ms for the status port to get a certain value
194 * (masked with 0x0f), returning zero if the value is obtained. Callers must
195 * hold applesmc_lock.
197 static int __wait_status(u8 val)
199 int us;
201 val = val & APPLESMC_STATUS_MASK;
203 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
204 udelay(us);
205 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
206 if (debug)
207 printk(KERN_DEBUG
208 "Waited %d us for status %x\n",
209 2 * us - APPLESMC_MIN_WAIT, val);
210 return 0;
214 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
215 val, inb(APPLESMC_CMD_PORT));
217 return -EIO;
221 * special treatment of command port - on newer macbooks, it seems necessary
222 * to resend the command byte before polling the status again. Callers must
223 * hold applesmc_lock.
225 static int send_command(u8 cmd)
227 int us;
228 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
229 outb(cmd, APPLESMC_CMD_PORT);
230 udelay(us);
231 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
232 return 0;
234 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
235 cmd, inb(APPLESMC_CMD_PORT));
236 return -EIO;
240 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
241 * Returns zero on success or a negative error on failure. Callers must
242 * hold applesmc_lock.
244 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
246 int i;
248 if (len > APPLESMC_MAX_DATA_LENGTH) {
249 printk(KERN_ERR "applesmc_read_key: cannot read more than "
250 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
251 return -EINVAL;
254 if (send_command(APPLESMC_READ_CMD))
255 return -EIO;
257 for (i = 0; i < 4; i++) {
258 outb(key[i], APPLESMC_DATA_PORT);
259 if (__wait_status(0x04))
260 return -EIO;
262 if (debug)
263 printk(KERN_DEBUG "<%s", key);
265 outb(len, APPLESMC_DATA_PORT);
266 if (debug)
267 printk(KERN_DEBUG ">%x", len);
269 for (i = 0; i < len; i++) {
270 if (__wait_status(0x05))
271 return -EIO;
272 buffer[i] = inb(APPLESMC_DATA_PORT);
273 if (debug)
274 printk(KERN_DEBUG "<%x", buffer[i]);
276 if (debug)
277 printk(KERN_DEBUG "\n");
279 return 0;
283 * applesmc_write_key - writes len bytes from buffer to a given key.
284 * Returns zero on success or a negative error on failure. Callers must
285 * hold applesmc_lock.
287 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
289 int i;
291 if (len > APPLESMC_MAX_DATA_LENGTH) {
292 printk(KERN_ERR "applesmc_write_key: cannot write more than "
293 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
294 return -EINVAL;
297 if (send_command(APPLESMC_WRITE_CMD))
298 return -EIO;
300 for (i = 0; i < 4; i++) {
301 outb(key[i], APPLESMC_DATA_PORT);
302 if (__wait_status(0x04))
303 return -EIO;
306 outb(len, APPLESMC_DATA_PORT);
308 for (i = 0; i < len; i++) {
309 if (__wait_status(0x04))
310 return -EIO;
311 outb(buffer[i], APPLESMC_DATA_PORT);
314 return 0;
318 * applesmc_get_key_at_index - get key at index, and put the result in key
319 * (char[6]). Returns zero on success or a negative error on failure. Callers
320 * must hold applesmc_lock.
322 static int applesmc_get_key_at_index(int index, char* key)
324 int i;
325 u8 readkey[4];
326 readkey[0] = index >> 24;
327 readkey[1] = index >> 16;
328 readkey[2] = index >> 8;
329 readkey[3] = index;
331 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
332 return -EIO;
334 for (i = 0; i < 4; i++) {
335 outb(readkey[i], APPLESMC_DATA_PORT);
336 if (__wait_status(0x04))
337 return -EIO;
340 outb(4, APPLESMC_DATA_PORT);
342 for (i = 0; i < 4; i++) {
343 if (__wait_status(0x05))
344 return -EIO;
345 key[i] = inb(APPLESMC_DATA_PORT);
347 key[4] = 0;
349 return 0;
353 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
354 * Returns zero on success or a negative error on failure. Callers must
355 * hold applesmc_lock.
357 static int applesmc_get_key_type(char* key, char* type)
359 int i;
361 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
362 return -EIO;
364 for (i = 0; i < 4; i++) {
365 outb(key[i], APPLESMC_DATA_PORT);
366 if (__wait_status(0x04))
367 return -EIO;
370 outb(6, APPLESMC_DATA_PORT);
372 for (i = 0; i < 6; i++) {
373 if (__wait_status(0x05))
374 return -EIO;
375 type[i] = inb(APPLESMC_DATA_PORT);
377 type[5] = 0;
379 return 0;
383 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
384 * hold applesmc_lock.
386 static int applesmc_read_motion_sensor(int index, s16* value)
388 u8 buffer[2];
389 int ret;
391 switch (index) {
392 case SENSOR_X:
393 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
394 break;
395 case SENSOR_Y:
396 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
397 break;
398 case SENSOR_Z:
399 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
400 break;
401 default:
402 ret = -EINVAL;
405 *value = ((s16)buffer[0] << 8) | buffer[1];
407 return ret;
411 * applesmc_device_init - initialize the accelerometer. Returns zero on success
412 * and negative error code on failure. Can sleep.
414 static int applesmc_device_init(void)
416 int total, ret = -ENXIO;
417 u8 buffer[2];
419 if (!applesmc_accelerometer)
420 return 0;
422 mutex_lock(&applesmc_lock);
424 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
425 if (debug)
426 printk(KERN_DEBUG "applesmc try %d\n", total);
427 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
428 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
429 if (total == INIT_TIMEOUT_MSECS) {
430 printk(KERN_DEBUG "applesmc: device has"
431 " already been initialized"
432 " (0x%02x, 0x%02x).\n",
433 buffer[0], buffer[1]);
434 } else {
435 printk(KERN_DEBUG "applesmc: device"
436 " successfully initialized"
437 " (0x%02x, 0x%02x).\n",
438 buffer[0], buffer[1]);
440 ret = 0;
441 goto out;
443 buffer[0] = 0xe0;
444 buffer[1] = 0x00;
445 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
446 msleep(INIT_WAIT_MSECS);
449 printk(KERN_WARNING "applesmc: failed to init the device\n");
451 out:
452 mutex_unlock(&applesmc_lock);
453 return ret;
457 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
458 * applesmc_lock.
460 static int applesmc_get_fan_count(void)
462 int ret;
463 u8 buffer[1];
465 mutex_lock(&applesmc_lock);
467 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
469 mutex_unlock(&applesmc_lock);
470 if (ret)
471 return ret;
472 else
473 return buffer[0];
476 /* Device model stuff */
477 static int applesmc_probe(struct platform_device *dev)
479 int ret;
481 ret = applesmc_device_init();
482 if (ret)
483 return ret;
485 printk(KERN_INFO "applesmc: device successfully initialized.\n");
486 return 0;
489 static int applesmc_resume(struct platform_device *dev)
491 return applesmc_device_init();
494 static struct platform_driver applesmc_driver = {
495 .probe = applesmc_probe,
496 .resume = applesmc_resume,
497 .driver = {
498 .name = "applesmc",
499 .owner = THIS_MODULE,
504 * applesmc_calibrate - Set our "resting" values. Callers must
505 * hold applesmc_lock.
507 static void applesmc_calibrate(void)
509 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
510 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
511 rest_x = -rest_x;
514 static void applesmc_idev_poll(struct input_polled_dev *dev)
516 struct input_dev *idev = dev->input;
517 s16 x, y;
519 mutex_lock(&applesmc_lock);
521 if (applesmc_read_motion_sensor(SENSOR_X, &x))
522 goto out;
523 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
524 goto out;
526 x = -x;
527 input_report_abs(idev, ABS_X, x - rest_x);
528 input_report_abs(idev, ABS_Y, y - rest_y);
529 input_sync(idev);
531 out:
532 mutex_unlock(&applesmc_lock);
535 /* Sysfs Files */
537 static ssize_t applesmc_name_show(struct device *dev,
538 struct device_attribute *attr, char *buf)
540 return snprintf(buf, PAGE_SIZE, "applesmc\n");
543 static ssize_t applesmc_position_show(struct device *dev,
544 struct device_attribute *attr, char *buf)
546 int ret;
547 s16 x, y, z;
549 mutex_lock(&applesmc_lock);
551 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
552 if (ret)
553 goto out;
554 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
555 if (ret)
556 goto out;
557 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
558 if (ret)
559 goto out;
561 out:
562 mutex_unlock(&applesmc_lock);
563 if (ret)
564 return ret;
565 else
566 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
569 static ssize_t applesmc_light_show(struct device *dev,
570 struct device_attribute *attr, char *sysfsbuf)
572 static int data_length;
573 int ret;
574 u8 left = 0, right = 0;
575 u8 buffer[10], query[6];
577 mutex_lock(&applesmc_lock);
579 if (!data_length) {
580 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
581 if (ret)
582 goto out;
583 data_length = clamp_val(query[0], 0, 10);
584 printk(KERN_INFO "applesmc: light sensor data length set to "
585 "%d\n", data_length);
588 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
589 left = buffer[2];
590 if (ret)
591 goto out;
592 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
593 right = buffer[2];
595 out:
596 mutex_unlock(&applesmc_lock);
597 if (ret)
598 return ret;
599 else
600 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
603 /* Displays degree Celsius * 1000 */
604 static ssize_t applesmc_show_temperature(struct device *dev,
605 struct device_attribute *devattr, char *sysfsbuf)
607 int ret;
608 u8 buffer[2];
609 unsigned int temp;
610 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
611 const char* key =
612 temperature_sensors_sets[applesmc_temperature_set][attr->index];
614 mutex_lock(&applesmc_lock);
616 ret = applesmc_read_key(key, buffer, 2);
617 temp = buffer[0]*1000;
618 temp += (buffer[1] >> 6) * 250;
620 mutex_unlock(&applesmc_lock);
622 if (ret)
623 return ret;
624 else
625 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
628 static ssize_t applesmc_show_fan_speed(struct device *dev,
629 struct device_attribute *attr, char *sysfsbuf)
631 int ret;
632 unsigned int speed = 0;
633 char newkey[5];
634 u8 buffer[2];
635 struct sensor_device_attribute_2 *sensor_attr =
636 to_sensor_dev_attr_2(attr);
638 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
639 newkey[1] = '0' + sensor_attr->index;
640 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
641 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
642 newkey[4] = 0;
644 mutex_lock(&applesmc_lock);
646 ret = applesmc_read_key(newkey, buffer, 2);
647 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
649 mutex_unlock(&applesmc_lock);
650 if (ret)
651 return ret;
652 else
653 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
656 static ssize_t applesmc_store_fan_speed(struct device *dev,
657 struct device_attribute *attr,
658 const char *sysfsbuf, size_t count)
660 int ret;
661 u32 speed;
662 char newkey[5];
663 u8 buffer[2];
664 struct sensor_device_attribute_2 *sensor_attr =
665 to_sensor_dev_attr_2(attr);
667 speed = simple_strtoul(sysfsbuf, NULL, 10);
669 if (speed > 0x4000) /* Bigger than a 14-bit value */
670 return -EINVAL;
672 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
673 newkey[1] = '0' + sensor_attr->index;
674 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
675 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
676 newkey[4] = 0;
678 mutex_lock(&applesmc_lock);
680 buffer[0] = (speed >> 6) & 0xff;
681 buffer[1] = (speed << 2) & 0xff;
682 ret = applesmc_write_key(newkey, buffer, 2);
684 mutex_unlock(&applesmc_lock);
685 if (ret)
686 return ret;
687 else
688 return count;
691 static ssize_t applesmc_show_fan_manual(struct device *dev,
692 struct device_attribute *devattr, char *sysfsbuf)
694 int ret;
695 u16 manual = 0;
696 u8 buffer[2];
697 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
699 mutex_lock(&applesmc_lock);
701 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
702 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
704 mutex_unlock(&applesmc_lock);
705 if (ret)
706 return ret;
707 else
708 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
711 static ssize_t applesmc_store_fan_manual(struct device *dev,
712 struct device_attribute *devattr,
713 const char *sysfsbuf, size_t count)
715 int ret;
716 u8 buffer[2];
717 u32 input;
718 u16 val;
719 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
721 input = simple_strtoul(sysfsbuf, NULL, 10);
723 mutex_lock(&applesmc_lock);
725 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
726 val = (buffer[0] << 8 | buffer[1]);
727 if (ret)
728 goto out;
730 if (input)
731 val = val | (0x01 << attr->index);
732 else
733 val = val & ~(0x01 << attr->index);
735 buffer[0] = (val >> 8) & 0xFF;
736 buffer[1] = val & 0xFF;
738 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
740 out:
741 mutex_unlock(&applesmc_lock);
742 if (ret)
743 return ret;
744 else
745 return count;
748 static ssize_t applesmc_show_fan_position(struct device *dev,
749 struct device_attribute *attr, char *sysfsbuf)
751 int ret;
752 char newkey[5];
753 u8 buffer[17];
754 struct sensor_device_attribute_2 *sensor_attr =
755 to_sensor_dev_attr_2(attr);
757 newkey[0] = FAN_POSITION[0];
758 newkey[1] = '0' + sensor_attr->index;
759 newkey[2] = FAN_POSITION[2];
760 newkey[3] = FAN_POSITION[3];
761 newkey[4] = 0;
763 mutex_lock(&applesmc_lock);
765 ret = applesmc_read_key(newkey, buffer, 16);
766 buffer[16] = 0;
768 mutex_unlock(&applesmc_lock);
769 if (ret)
770 return ret;
771 else
772 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
775 static ssize_t applesmc_calibrate_show(struct device *dev,
776 struct device_attribute *attr, char *sysfsbuf)
778 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
781 static ssize_t applesmc_calibrate_store(struct device *dev,
782 struct device_attribute *attr, const char *sysfsbuf, size_t count)
784 mutex_lock(&applesmc_lock);
785 applesmc_calibrate();
786 mutex_unlock(&applesmc_lock);
788 return count;
791 /* Store the next backlight value to be written by the work */
792 static unsigned int backlight_value;
794 static void applesmc_backlight_set(struct work_struct *work)
796 u8 buffer[2];
798 mutex_lock(&applesmc_lock);
799 buffer[0] = backlight_value;
800 buffer[1] = 0x00;
801 applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
802 mutex_unlock(&applesmc_lock);
804 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
806 static void applesmc_brightness_set(struct led_classdev *led_cdev,
807 enum led_brightness value)
809 int ret;
811 backlight_value = value;
812 ret = queue_work(applesmc_led_wq, &backlight_work);
814 if (debug && (!ret))
815 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
818 static ssize_t applesmc_key_count_show(struct device *dev,
819 struct device_attribute *attr, char *sysfsbuf)
821 int ret;
822 u8 buffer[4];
823 u32 count;
825 mutex_lock(&applesmc_lock);
827 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
828 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
829 ((u32)buffer[2]<<8) + buffer[3];
831 mutex_unlock(&applesmc_lock);
832 if (ret)
833 return ret;
834 else
835 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
838 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
839 struct device_attribute *attr, char *sysfsbuf)
841 char key[5];
842 char info[6];
843 int ret;
845 mutex_lock(&applesmc_lock);
847 ret = applesmc_get_key_at_index(key_at_index, key);
849 if (ret || !key[0]) {
850 mutex_unlock(&applesmc_lock);
852 return -EINVAL;
855 ret = applesmc_get_key_type(key, info);
857 if (ret) {
858 mutex_unlock(&applesmc_lock);
860 return ret;
864 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
865 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
867 ret = applesmc_read_key(key, sysfsbuf, info[0]);
869 mutex_unlock(&applesmc_lock);
871 if (!ret) {
872 return info[0];
873 } else {
874 return ret;
878 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
879 struct device_attribute *attr, char *sysfsbuf)
881 char key[5];
882 char info[6];
883 int ret;
885 mutex_lock(&applesmc_lock);
887 ret = applesmc_get_key_at_index(key_at_index, key);
889 if (ret || !key[0]) {
890 mutex_unlock(&applesmc_lock);
892 return -EINVAL;
895 ret = applesmc_get_key_type(key, info);
897 mutex_unlock(&applesmc_lock);
899 if (!ret)
900 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
901 else
902 return ret;
905 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
906 struct device_attribute *attr, char *sysfsbuf)
908 char key[5];
909 char info[6];
910 int ret;
912 mutex_lock(&applesmc_lock);
914 ret = applesmc_get_key_at_index(key_at_index, key);
916 if (ret || !key[0]) {
917 mutex_unlock(&applesmc_lock);
919 return -EINVAL;
922 ret = applesmc_get_key_type(key, info);
924 mutex_unlock(&applesmc_lock);
926 if (!ret)
927 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
928 else
929 return ret;
932 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
933 struct device_attribute *attr, char *sysfsbuf)
935 char key[5];
936 int ret;
938 mutex_lock(&applesmc_lock);
940 ret = applesmc_get_key_at_index(key_at_index, key);
942 mutex_unlock(&applesmc_lock);
944 if (!ret && key[0])
945 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
946 else
947 return -EINVAL;
950 static ssize_t applesmc_key_at_index_show(struct device *dev,
951 struct device_attribute *attr, char *sysfsbuf)
953 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
956 static ssize_t applesmc_key_at_index_store(struct device *dev,
957 struct device_attribute *attr, const char *sysfsbuf, size_t count)
959 mutex_lock(&applesmc_lock);
961 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
963 mutex_unlock(&applesmc_lock);
965 return count;
968 static struct led_classdev applesmc_backlight = {
969 .name = "smc::kbd_backlight",
970 .default_trigger = "nand-disk",
971 .brightness_set = applesmc_brightness_set,
974 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
976 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
977 static DEVICE_ATTR(calibrate, 0644,
978 applesmc_calibrate_show, applesmc_calibrate_store);
980 static struct attribute *accelerometer_attributes[] = {
981 &dev_attr_position.attr,
982 &dev_attr_calibrate.attr,
983 NULL
986 static const struct attribute_group accelerometer_attributes_group =
987 { .attrs = accelerometer_attributes };
989 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
991 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
992 static DEVICE_ATTR(key_at_index, 0644,
993 applesmc_key_at_index_show, applesmc_key_at_index_store);
994 static DEVICE_ATTR(key_at_index_name, 0444,
995 applesmc_key_at_index_name_show, NULL);
996 static DEVICE_ATTR(key_at_index_type, 0444,
997 applesmc_key_at_index_type_show, NULL);
998 static DEVICE_ATTR(key_at_index_data_length, 0444,
999 applesmc_key_at_index_data_length_show, NULL);
1000 static DEVICE_ATTR(key_at_index_data, 0444,
1001 applesmc_key_at_index_read_show, NULL);
1003 static struct attribute *key_enumeration_attributes[] = {
1004 &dev_attr_key_count.attr,
1005 &dev_attr_key_at_index.attr,
1006 &dev_attr_key_at_index_name.attr,
1007 &dev_attr_key_at_index_type.attr,
1008 &dev_attr_key_at_index_data_length.attr,
1009 &dev_attr_key_at_index_data.attr,
1010 NULL
1013 static const struct attribute_group key_enumeration_group =
1014 { .attrs = key_enumeration_attributes };
1017 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1018 * - show actual speed
1019 * - show/store minimum speed
1020 * - show maximum speed
1021 * - show safe speed
1022 * - show/store target speed
1023 * - show/store manual mode
1025 #define sysfs_fan_speeds_offset(offset) \
1026 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1027 applesmc_show_fan_speed, NULL, 0, offset-1); \
1029 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1030 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1032 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1033 applesmc_show_fan_speed, NULL, 2, offset-1); \
1035 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1036 applesmc_show_fan_speed, NULL, 3, offset-1); \
1038 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1039 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1041 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1042 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1044 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1045 applesmc_show_fan_position, NULL, offset-1); \
1047 static struct attribute *fan##offset##_attributes[] = { \
1048 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1049 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1050 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1051 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1052 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1053 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1054 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1055 NULL \
1059 * Create the needed functions for each fan using the macro defined above
1060 * (4 fans are supported)
1062 sysfs_fan_speeds_offset(1);
1063 sysfs_fan_speeds_offset(2);
1064 sysfs_fan_speeds_offset(3);
1065 sysfs_fan_speeds_offset(4);
1067 static const struct attribute_group fan_attribute_groups[] = {
1068 { .attrs = fan1_attributes },
1069 { .attrs = fan2_attributes },
1070 { .attrs = fan3_attributes },
1071 { .attrs = fan4_attributes },
1075 * Temperature sensors sysfs entries.
1077 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1078 applesmc_show_temperature, NULL, 0);
1079 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1080 applesmc_show_temperature, NULL, 1);
1081 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1082 applesmc_show_temperature, NULL, 2);
1083 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1084 applesmc_show_temperature, NULL, 3);
1085 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1086 applesmc_show_temperature, NULL, 4);
1087 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1088 applesmc_show_temperature, NULL, 5);
1089 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1090 applesmc_show_temperature, NULL, 6);
1091 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1092 applesmc_show_temperature, NULL, 7);
1093 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1094 applesmc_show_temperature, NULL, 8);
1095 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1096 applesmc_show_temperature, NULL, 9);
1097 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1098 applesmc_show_temperature, NULL, 10);
1099 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1100 applesmc_show_temperature, NULL, 11);
1101 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1102 applesmc_show_temperature, NULL, 12);
1103 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1104 applesmc_show_temperature, NULL, 13);
1105 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1106 applesmc_show_temperature, NULL, 14);
1107 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1108 applesmc_show_temperature, NULL, 15);
1109 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1110 applesmc_show_temperature, NULL, 16);
1111 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1112 applesmc_show_temperature, NULL, 17);
1113 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1114 applesmc_show_temperature, NULL, 18);
1115 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1116 applesmc_show_temperature, NULL, 19);
1117 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1118 applesmc_show_temperature, NULL, 20);
1119 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1120 applesmc_show_temperature, NULL, 21);
1121 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1122 applesmc_show_temperature, NULL, 22);
1123 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1124 applesmc_show_temperature, NULL, 23);
1125 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1126 applesmc_show_temperature, NULL, 24);
1127 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1128 applesmc_show_temperature, NULL, 25);
1129 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1130 applesmc_show_temperature, NULL, 26);
1131 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1132 applesmc_show_temperature, NULL, 27);
1133 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1134 applesmc_show_temperature, NULL, 28);
1135 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1136 applesmc_show_temperature, NULL, 29);
1137 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1138 applesmc_show_temperature, NULL, 30);
1139 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1140 applesmc_show_temperature, NULL, 31);
1141 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1142 applesmc_show_temperature, NULL, 32);
1143 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1144 applesmc_show_temperature, NULL, 33);
1145 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1146 applesmc_show_temperature, NULL, 34);
1148 static struct attribute *temperature_attributes[] = {
1149 &sensor_dev_attr_temp1_input.dev_attr.attr,
1150 &sensor_dev_attr_temp2_input.dev_attr.attr,
1151 &sensor_dev_attr_temp3_input.dev_attr.attr,
1152 &sensor_dev_attr_temp4_input.dev_attr.attr,
1153 &sensor_dev_attr_temp5_input.dev_attr.attr,
1154 &sensor_dev_attr_temp6_input.dev_attr.attr,
1155 &sensor_dev_attr_temp7_input.dev_attr.attr,
1156 &sensor_dev_attr_temp8_input.dev_attr.attr,
1157 &sensor_dev_attr_temp9_input.dev_attr.attr,
1158 &sensor_dev_attr_temp10_input.dev_attr.attr,
1159 &sensor_dev_attr_temp11_input.dev_attr.attr,
1160 &sensor_dev_attr_temp12_input.dev_attr.attr,
1161 &sensor_dev_attr_temp13_input.dev_attr.attr,
1162 &sensor_dev_attr_temp14_input.dev_attr.attr,
1163 &sensor_dev_attr_temp15_input.dev_attr.attr,
1164 &sensor_dev_attr_temp16_input.dev_attr.attr,
1165 &sensor_dev_attr_temp17_input.dev_attr.attr,
1166 &sensor_dev_attr_temp18_input.dev_attr.attr,
1167 &sensor_dev_attr_temp19_input.dev_attr.attr,
1168 &sensor_dev_attr_temp20_input.dev_attr.attr,
1169 &sensor_dev_attr_temp21_input.dev_attr.attr,
1170 &sensor_dev_attr_temp22_input.dev_attr.attr,
1171 &sensor_dev_attr_temp23_input.dev_attr.attr,
1172 &sensor_dev_attr_temp24_input.dev_attr.attr,
1173 &sensor_dev_attr_temp25_input.dev_attr.attr,
1174 &sensor_dev_attr_temp26_input.dev_attr.attr,
1175 &sensor_dev_attr_temp27_input.dev_attr.attr,
1176 &sensor_dev_attr_temp28_input.dev_attr.attr,
1177 &sensor_dev_attr_temp29_input.dev_attr.attr,
1178 &sensor_dev_attr_temp30_input.dev_attr.attr,
1179 &sensor_dev_attr_temp31_input.dev_attr.attr,
1180 &sensor_dev_attr_temp32_input.dev_attr.attr,
1181 &sensor_dev_attr_temp33_input.dev_attr.attr,
1182 &sensor_dev_attr_temp34_input.dev_attr.attr,
1183 &sensor_dev_attr_temp35_input.dev_attr.attr,
1184 NULL
1187 static const struct attribute_group temperature_attributes_group =
1188 { .attrs = temperature_attributes };
1190 /* Module stuff */
1193 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1195 static int applesmc_dmi_match(const struct dmi_system_id *id)
1197 int i = 0;
1198 struct dmi_match_data* dmi_data = id->driver_data;
1199 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1200 applesmc_accelerometer = dmi_data->accelerometer;
1201 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1202 applesmc_accelerometer ? "with" : "without");
1203 applesmc_light = dmi_data->light;
1204 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1205 applesmc_light ? "with" : "without");
1207 applesmc_temperature_set = dmi_data->temperature_set;
1208 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1209 i++;
1210 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1211 return 1;
1214 /* Create accelerometer ressources */
1215 static int applesmc_create_accelerometer(void)
1217 struct input_dev *idev;
1218 int ret;
1220 ret = sysfs_create_group(&pdev->dev.kobj,
1221 &accelerometer_attributes_group);
1222 if (ret)
1223 goto out;
1225 applesmc_idev = input_allocate_polled_device();
1226 if (!applesmc_idev) {
1227 ret = -ENOMEM;
1228 goto out_sysfs;
1231 applesmc_idev->poll = applesmc_idev_poll;
1232 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1234 /* initial calibrate for the input device */
1235 applesmc_calibrate();
1237 /* initialize the input device */
1238 idev = applesmc_idev->input;
1239 idev->name = "applesmc";
1240 idev->id.bustype = BUS_HOST;
1241 idev->dev.parent = &pdev->dev;
1242 idev->evbit[0] = BIT_MASK(EV_ABS);
1243 input_set_abs_params(idev, ABS_X,
1244 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1245 input_set_abs_params(idev, ABS_Y,
1246 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1248 ret = input_register_polled_device(applesmc_idev);
1249 if (ret)
1250 goto out_idev;
1252 return 0;
1254 out_idev:
1255 input_free_polled_device(applesmc_idev);
1257 out_sysfs:
1258 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1260 out:
1261 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1262 return ret;
1265 /* Release all ressources used by the accelerometer */
1266 static void applesmc_release_accelerometer(void)
1268 input_unregister_polled_device(applesmc_idev);
1269 input_free_polled_device(applesmc_idev);
1270 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1273 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1274 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1275 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1276 /* MacBook2: accelerometer and temperature set 1 */
1277 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1278 /* MacBook: accelerometer and temperature set 2 */
1279 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1280 /* MacMini: temperature set 3 */
1281 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1282 /* MacPro: temperature set 4 */
1283 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1284 /* iMac: temperature set 5 */
1285 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1286 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1287 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1288 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1289 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1290 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1291 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1292 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1293 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1294 /* iMac 5: light sensor only, temperature set 10 */
1295 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1296 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1297 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
1298 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1299 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
1300 /* iMac 8: light sensor only, temperature set 13 */
1301 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
1302 /* iMac 6: light sensor only, temperature set 14 */
1303 { .accelerometer = 0, .light = 0, .temperature_set = 14 },
1306 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1307 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1308 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1309 { applesmc_dmi_match, "Apple MacBook Air", {
1310 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1311 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1312 &applesmc_dmi_data[7]},
1313 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1314 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1315 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1316 &applesmc_dmi_data[12]},
1317 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1318 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1319 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1320 &applesmc_dmi_data[8]},
1321 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1322 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1323 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1324 &applesmc_dmi_data[9]},
1325 { applesmc_dmi_match, "Apple MacBook Pro", {
1326 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1327 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1328 &applesmc_dmi_data[0]},
1329 { applesmc_dmi_match, "Apple MacBook (v2)", {
1330 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1331 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1332 &applesmc_dmi_data[1]},
1333 { applesmc_dmi_match, "Apple MacBook (v3)", {
1334 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1335 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1336 &applesmc_dmi_data[6]},
1337 { applesmc_dmi_match, "Apple MacBook 4", {
1338 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1339 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1340 &applesmc_dmi_data[6]},
1341 { applesmc_dmi_match, "Apple MacBook 5", {
1342 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1343 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1344 &applesmc_dmi_data[11]},
1345 { applesmc_dmi_match, "Apple MacBook", {
1346 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1347 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1348 &applesmc_dmi_data[2]},
1349 { applesmc_dmi_match, "Apple Macmini", {
1350 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1351 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1352 &applesmc_dmi_data[3]},
1353 { applesmc_dmi_match, "Apple MacPro2", {
1354 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1355 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1356 &applesmc_dmi_data[4]},
1357 { applesmc_dmi_match, "Apple MacPro", {
1358 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1359 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1360 &applesmc_dmi_data[4]},
1361 { applesmc_dmi_match, "Apple iMac 8", {
1362 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1363 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1364 &applesmc_dmi_data[13]},
1365 { applesmc_dmi_match, "Apple iMac 6", {
1366 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1367 DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
1368 &applesmc_dmi_data[14]},
1369 { applesmc_dmi_match, "Apple iMac 5", {
1370 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1371 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1372 &applesmc_dmi_data[10]},
1373 { applesmc_dmi_match, "Apple iMac", {
1374 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1375 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1376 &applesmc_dmi_data[5]},
1377 { .ident = NULL }
1380 static int __init applesmc_init(void)
1382 int ret;
1383 int count;
1384 int i;
1386 if (!dmi_check_system(applesmc_whitelist)) {
1387 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1388 ret = -ENODEV;
1389 goto out;
1392 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1393 "applesmc")) {
1394 ret = -ENXIO;
1395 goto out;
1398 ret = platform_driver_register(&applesmc_driver);
1399 if (ret)
1400 goto out_region;
1402 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1403 NULL, 0);
1404 if (IS_ERR(pdev)) {
1405 ret = PTR_ERR(pdev);
1406 goto out_driver;
1409 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1410 if (ret)
1411 goto out_device;
1413 /* Create key enumeration sysfs files */
1414 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1415 if (ret)
1416 goto out_name;
1418 /* create fan files */
1419 count = applesmc_get_fan_count();
1420 if (count < 0) {
1421 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1422 } else {
1423 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1425 switch (count) {
1426 default:
1427 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1428 " but at most 4 fans are supported"
1429 " by the driver.\n");
1430 case 4:
1431 ret = sysfs_create_group(&pdev->dev.kobj,
1432 &fan_attribute_groups[3]);
1433 if (ret)
1434 goto out_key_enumeration;
1435 case 3:
1436 ret = sysfs_create_group(&pdev->dev.kobj,
1437 &fan_attribute_groups[2]);
1438 if (ret)
1439 goto out_key_enumeration;
1440 case 2:
1441 ret = sysfs_create_group(&pdev->dev.kobj,
1442 &fan_attribute_groups[1]);
1443 if (ret)
1444 goto out_key_enumeration;
1445 case 1:
1446 ret = sysfs_create_group(&pdev->dev.kobj,
1447 &fan_attribute_groups[0]);
1448 if (ret)
1449 goto out_fan_1;
1450 case 0:
1455 for (i = 0;
1456 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1457 i++) {
1458 if (temperature_attributes[i] == NULL) {
1459 printk(KERN_ERR "applesmc: More temperature sensors "
1460 "in temperature_sensors_sets (at least %i)"
1461 "than available sysfs files in "
1462 "temperature_attributes (%i), please report "
1463 "this bug.\n", i, i-1);
1464 goto out_temperature;
1466 ret = sysfs_create_file(&pdev->dev.kobj,
1467 temperature_attributes[i]);
1468 if (ret)
1469 goto out_temperature;
1472 if (applesmc_accelerometer) {
1473 ret = applesmc_create_accelerometer();
1474 if (ret)
1475 goto out_temperature;
1478 if (applesmc_light) {
1479 /* Add light sensor file */
1480 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1481 if (ret)
1482 goto out_accelerometer;
1484 /* Create the workqueue */
1485 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1486 if (!applesmc_led_wq) {
1487 ret = -ENOMEM;
1488 goto out_light_sysfs;
1491 /* register as a led device */
1492 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1493 if (ret < 0)
1494 goto out_light_wq;
1497 hwmon_dev = hwmon_device_register(&pdev->dev);
1498 if (IS_ERR(hwmon_dev)) {
1499 ret = PTR_ERR(hwmon_dev);
1500 goto out_light_ledclass;
1503 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1505 return 0;
1507 out_light_ledclass:
1508 if (applesmc_light)
1509 led_classdev_unregister(&applesmc_backlight);
1510 out_light_wq:
1511 if (applesmc_light)
1512 destroy_workqueue(applesmc_led_wq);
1513 out_light_sysfs:
1514 if (applesmc_light)
1515 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1516 out_accelerometer:
1517 if (applesmc_accelerometer)
1518 applesmc_release_accelerometer();
1519 out_temperature:
1520 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1521 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1522 out_fan_1:
1523 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1524 out_key_enumeration:
1525 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1526 out_name:
1527 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1528 out_device:
1529 platform_device_unregister(pdev);
1530 out_driver:
1531 platform_driver_unregister(&applesmc_driver);
1532 out_region:
1533 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1534 out:
1535 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1536 return ret;
1539 static void __exit applesmc_exit(void)
1541 hwmon_device_unregister(hwmon_dev);
1542 if (applesmc_light) {
1543 led_classdev_unregister(&applesmc_backlight);
1544 destroy_workqueue(applesmc_led_wq);
1545 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1547 if (applesmc_accelerometer)
1548 applesmc_release_accelerometer();
1549 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1550 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1551 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1552 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1553 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1554 platform_device_unregister(pdev);
1555 platform_driver_unregister(&applesmc_driver);
1556 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1558 printk(KERN_INFO "applesmc: driver unloaded.\n");
1561 module_init(applesmc_init);
1562 module_exit(applesmc_exit);
1564 MODULE_AUTHOR("Nicolas Boichat");
1565 MODULE_DESCRIPTION("Apple SMC");
1566 MODULE_LICENSE("GPL v2");
1567 MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);