hwmon: applesmc: add support for Macbook 4
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / hwmon / applesmc.c
blob488e45cd43d7ab4edb17fd17f6a98ce7bfd1bcf3
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 },
133 /* List of keys used to read/write fan speeds */
134 static const char* fan_speed_keys[] = {
135 FAN_ACTUAL_SPEED,
136 FAN_MIN_SPEED,
137 FAN_MAX_SPEED,
138 FAN_SAFE_SPEED,
139 FAN_TARGET_SPEED
142 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
143 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
145 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
146 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
147 #define APPLESMC_INPUT_FLAT 4
149 #define SENSOR_X 0
150 #define SENSOR_Y 1
151 #define SENSOR_Z 2
153 /* Structure to be passed to DMI_MATCH function */
154 struct dmi_match_data {
155 /* Indicates whether this computer has an accelerometer. */
156 int accelerometer;
157 /* Indicates whether this computer has light sensors and keyboard backlight. */
158 int light;
159 /* Indicates which temperature sensors set to use. */
160 int temperature_set;
163 static const int debug;
164 static struct platform_device *pdev;
165 static s16 rest_x;
166 static s16 rest_y;
167 static struct device *hwmon_dev;
168 static struct input_polled_dev *applesmc_idev;
170 /* Indicates whether this computer has an accelerometer. */
171 static unsigned int applesmc_accelerometer;
173 /* Indicates whether this computer has light sensors and keyboard backlight. */
174 static unsigned int applesmc_light;
176 /* Indicates which temperature sensors set to use. */
177 static unsigned int applesmc_temperature_set;
179 static DEFINE_MUTEX(applesmc_lock);
182 * Last index written to key_at_index sysfs file, and value to use for all other
183 * key_at_index_* sysfs files.
185 static unsigned int key_at_index;
187 static struct workqueue_struct *applesmc_led_wq;
190 * __wait_status - Wait up to 32ms for the status port to get a certain value
191 * (masked with 0x0f), returning zero if the value is obtained. Callers must
192 * hold applesmc_lock.
194 static int __wait_status(u8 val)
196 int us;
198 val = val & APPLESMC_STATUS_MASK;
200 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
201 udelay(us);
202 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
203 if (debug)
204 printk(KERN_DEBUG
205 "Waited %d us for status %x\n",
206 2 * us - APPLESMC_MIN_WAIT, val);
207 return 0;
211 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
212 val, inb(APPLESMC_CMD_PORT));
214 return -EIO;
218 * special treatment of command port - on newer macbooks, it seems necessary
219 * to resend the command byte before polling the status again. Callers must
220 * hold applesmc_lock.
222 static int send_command(u8 cmd)
224 int us;
225 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
226 outb(cmd, APPLESMC_CMD_PORT);
227 udelay(us);
228 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
229 return 0;
231 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
232 cmd, inb(APPLESMC_CMD_PORT));
233 return -EIO;
237 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
238 * Returns zero on success or a negative error on failure. Callers must
239 * hold applesmc_lock.
241 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
243 int i;
245 if (len > APPLESMC_MAX_DATA_LENGTH) {
246 printk(KERN_ERR "applesmc_read_key: cannot read more than "
247 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
248 return -EINVAL;
251 if (send_command(APPLESMC_READ_CMD))
252 return -EIO;
254 for (i = 0; i < 4; i++) {
255 outb(key[i], APPLESMC_DATA_PORT);
256 if (__wait_status(0x04))
257 return -EIO;
259 if (debug)
260 printk(KERN_DEBUG "<%s", key);
262 outb(len, APPLESMC_DATA_PORT);
263 if (debug)
264 printk(KERN_DEBUG ">%x", len);
266 for (i = 0; i < len; i++) {
267 if (__wait_status(0x05))
268 return -EIO;
269 buffer[i] = inb(APPLESMC_DATA_PORT);
270 if (debug)
271 printk(KERN_DEBUG "<%x", buffer[i]);
273 if (debug)
274 printk(KERN_DEBUG "\n");
276 return 0;
280 * applesmc_write_key - writes len bytes from buffer to a given key.
281 * Returns zero on success or a negative error on failure. Callers must
282 * hold applesmc_lock.
284 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
286 int i;
288 if (len > APPLESMC_MAX_DATA_LENGTH) {
289 printk(KERN_ERR "applesmc_write_key: cannot write more than "
290 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
291 return -EINVAL;
294 if (send_command(APPLESMC_WRITE_CMD))
295 return -EIO;
297 for (i = 0; i < 4; i++) {
298 outb(key[i], APPLESMC_DATA_PORT);
299 if (__wait_status(0x04))
300 return -EIO;
303 outb(len, APPLESMC_DATA_PORT);
305 for (i = 0; i < len; i++) {
306 if (__wait_status(0x04))
307 return -EIO;
308 outb(buffer[i], APPLESMC_DATA_PORT);
311 return 0;
315 * applesmc_get_key_at_index - get key at index, and put the result in key
316 * (char[6]). Returns zero on success or a negative error on failure. Callers
317 * must hold applesmc_lock.
319 static int applesmc_get_key_at_index(int index, char* key)
321 int i;
322 u8 readkey[4];
323 readkey[0] = index >> 24;
324 readkey[1] = index >> 16;
325 readkey[2] = index >> 8;
326 readkey[3] = index;
328 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
329 return -EIO;
331 for (i = 0; i < 4; i++) {
332 outb(readkey[i], APPLESMC_DATA_PORT);
333 if (__wait_status(0x04))
334 return -EIO;
337 outb(4, APPLESMC_DATA_PORT);
339 for (i = 0; i < 4; i++) {
340 if (__wait_status(0x05))
341 return -EIO;
342 key[i] = inb(APPLESMC_DATA_PORT);
344 key[4] = 0;
346 return 0;
350 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
351 * Returns zero on success or a negative error on failure. Callers must
352 * hold applesmc_lock.
354 static int applesmc_get_key_type(char* key, char* type)
356 int i;
358 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
359 return -EIO;
361 for (i = 0; i < 4; i++) {
362 outb(key[i], APPLESMC_DATA_PORT);
363 if (__wait_status(0x04))
364 return -EIO;
367 outb(6, APPLESMC_DATA_PORT);
369 for (i = 0; i < 6; i++) {
370 if (__wait_status(0x05))
371 return -EIO;
372 type[i] = inb(APPLESMC_DATA_PORT);
374 type[5] = 0;
376 return 0;
380 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
381 * hold applesmc_lock.
383 static int applesmc_read_motion_sensor(int index, s16* value)
385 u8 buffer[2];
386 int ret;
388 switch (index) {
389 case SENSOR_X:
390 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
391 break;
392 case SENSOR_Y:
393 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
394 break;
395 case SENSOR_Z:
396 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
397 break;
398 default:
399 ret = -EINVAL;
402 *value = ((s16)buffer[0] << 8) | buffer[1];
404 return ret;
408 * applesmc_device_init - initialize the accelerometer. Returns zero on success
409 * and negative error code on failure. Can sleep.
411 static int applesmc_device_init(void)
413 int total, ret = -ENXIO;
414 u8 buffer[2];
416 if (!applesmc_accelerometer)
417 return 0;
419 mutex_lock(&applesmc_lock);
421 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
422 if (debug)
423 printk(KERN_DEBUG "applesmc try %d\n", total);
424 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
425 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
426 if (total == INIT_TIMEOUT_MSECS) {
427 printk(KERN_DEBUG "applesmc: device has"
428 " already been initialized"
429 " (0x%02x, 0x%02x).\n",
430 buffer[0], buffer[1]);
431 } else {
432 printk(KERN_DEBUG "applesmc: device"
433 " successfully initialized"
434 " (0x%02x, 0x%02x).\n",
435 buffer[0], buffer[1]);
437 ret = 0;
438 goto out;
440 buffer[0] = 0xe0;
441 buffer[1] = 0x00;
442 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
443 msleep(INIT_WAIT_MSECS);
446 printk(KERN_WARNING "applesmc: failed to init the device\n");
448 out:
449 mutex_unlock(&applesmc_lock);
450 return ret;
454 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
455 * applesmc_lock.
457 static int applesmc_get_fan_count(void)
459 int ret;
460 u8 buffer[1];
462 mutex_lock(&applesmc_lock);
464 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
466 mutex_unlock(&applesmc_lock);
467 if (ret)
468 return ret;
469 else
470 return buffer[0];
473 /* Device model stuff */
474 static int applesmc_probe(struct platform_device *dev)
476 int ret;
478 ret = applesmc_device_init();
479 if (ret)
480 return ret;
482 printk(KERN_INFO "applesmc: device successfully initialized.\n");
483 return 0;
486 static int applesmc_resume(struct platform_device *dev)
488 return applesmc_device_init();
491 static struct platform_driver applesmc_driver = {
492 .probe = applesmc_probe,
493 .resume = applesmc_resume,
494 .driver = {
495 .name = "applesmc",
496 .owner = THIS_MODULE,
501 * applesmc_calibrate - Set our "resting" values. Callers must
502 * hold applesmc_lock.
504 static void applesmc_calibrate(void)
506 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
507 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
508 rest_x = -rest_x;
511 static void applesmc_idev_poll(struct input_polled_dev *dev)
513 struct input_dev *idev = dev->input;
514 s16 x, y;
516 mutex_lock(&applesmc_lock);
518 if (applesmc_read_motion_sensor(SENSOR_X, &x))
519 goto out;
520 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
521 goto out;
523 x = -x;
524 input_report_abs(idev, ABS_X, x - rest_x);
525 input_report_abs(idev, ABS_Y, y - rest_y);
526 input_sync(idev);
528 out:
529 mutex_unlock(&applesmc_lock);
532 /* Sysfs Files */
534 static ssize_t applesmc_name_show(struct device *dev,
535 struct device_attribute *attr, char *buf)
537 return snprintf(buf, PAGE_SIZE, "applesmc\n");
540 static ssize_t applesmc_position_show(struct device *dev,
541 struct device_attribute *attr, char *buf)
543 int ret;
544 s16 x, y, z;
546 mutex_lock(&applesmc_lock);
548 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
549 if (ret)
550 goto out;
551 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
552 if (ret)
553 goto out;
554 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
555 if (ret)
556 goto out;
558 out:
559 mutex_unlock(&applesmc_lock);
560 if (ret)
561 return ret;
562 else
563 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
566 static ssize_t applesmc_light_show(struct device *dev,
567 struct device_attribute *attr, char *sysfsbuf)
569 static int data_length;
570 int ret;
571 u8 left = 0, right = 0;
572 u8 buffer[10], query[6];
574 mutex_lock(&applesmc_lock);
576 if (!data_length) {
577 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
578 if (ret)
579 goto out;
580 data_length = clamp_val(query[0], 0, 10);
581 printk(KERN_INFO "applesmc: light sensor data length set to "
582 "%d\n", data_length);
585 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
586 left = buffer[2];
587 if (ret)
588 goto out;
589 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
590 right = buffer[2];
592 out:
593 mutex_unlock(&applesmc_lock);
594 if (ret)
595 return ret;
596 else
597 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
600 /* Displays degree Celsius * 1000 */
601 static ssize_t applesmc_show_temperature(struct device *dev,
602 struct device_attribute *devattr, char *sysfsbuf)
604 int ret;
605 u8 buffer[2];
606 unsigned int temp;
607 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
608 const char* key =
609 temperature_sensors_sets[applesmc_temperature_set][attr->index];
611 mutex_lock(&applesmc_lock);
613 ret = applesmc_read_key(key, buffer, 2);
614 temp = buffer[0]*1000;
615 temp += (buffer[1] >> 6) * 250;
617 mutex_unlock(&applesmc_lock);
619 if (ret)
620 return ret;
621 else
622 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
625 static ssize_t applesmc_show_fan_speed(struct device *dev,
626 struct device_attribute *attr, char *sysfsbuf)
628 int ret;
629 unsigned int speed = 0;
630 char newkey[5];
631 u8 buffer[2];
632 struct sensor_device_attribute_2 *sensor_attr =
633 to_sensor_dev_attr_2(attr);
635 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
636 newkey[1] = '0' + sensor_attr->index;
637 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
638 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
639 newkey[4] = 0;
641 mutex_lock(&applesmc_lock);
643 ret = applesmc_read_key(newkey, buffer, 2);
644 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
646 mutex_unlock(&applesmc_lock);
647 if (ret)
648 return ret;
649 else
650 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
653 static ssize_t applesmc_store_fan_speed(struct device *dev,
654 struct device_attribute *attr,
655 const char *sysfsbuf, size_t count)
657 int ret;
658 u32 speed;
659 char newkey[5];
660 u8 buffer[2];
661 struct sensor_device_attribute_2 *sensor_attr =
662 to_sensor_dev_attr_2(attr);
664 speed = simple_strtoul(sysfsbuf, NULL, 10);
666 if (speed > 0x4000) /* Bigger than a 14-bit value */
667 return -EINVAL;
669 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
670 newkey[1] = '0' + sensor_attr->index;
671 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
672 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
673 newkey[4] = 0;
675 mutex_lock(&applesmc_lock);
677 buffer[0] = (speed >> 6) & 0xff;
678 buffer[1] = (speed << 2) & 0xff;
679 ret = applesmc_write_key(newkey, buffer, 2);
681 mutex_unlock(&applesmc_lock);
682 if (ret)
683 return ret;
684 else
685 return count;
688 static ssize_t applesmc_show_fan_manual(struct device *dev,
689 struct device_attribute *devattr, char *sysfsbuf)
691 int ret;
692 u16 manual = 0;
693 u8 buffer[2];
694 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
696 mutex_lock(&applesmc_lock);
698 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
699 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
701 mutex_unlock(&applesmc_lock);
702 if (ret)
703 return ret;
704 else
705 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
708 static ssize_t applesmc_store_fan_manual(struct device *dev,
709 struct device_attribute *devattr,
710 const char *sysfsbuf, size_t count)
712 int ret;
713 u8 buffer[2];
714 u32 input;
715 u16 val;
716 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
718 input = simple_strtoul(sysfsbuf, NULL, 10);
720 mutex_lock(&applesmc_lock);
722 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
723 val = (buffer[0] << 8 | buffer[1]);
724 if (ret)
725 goto out;
727 if (input)
728 val = val | (0x01 << attr->index);
729 else
730 val = val & ~(0x01 << attr->index);
732 buffer[0] = (val >> 8) & 0xFF;
733 buffer[1] = val & 0xFF;
735 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
737 out:
738 mutex_unlock(&applesmc_lock);
739 if (ret)
740 return ret;
741 else
742 return count;
745 static ssize_t applesmc_show_fan_position(struct device *dev,
746 struct device_attribute *attr, char *sysfsbuf)
748 int ret;
749 char newkey[5];
750 u8 buffer[17];
751 struct sensor_device_attribute_2 *sensor_attr =
752 to_sensor_dev_attr_2(attr);
754 newkey[0] = FAN_POSITION[0];
755 newkey[1] = '0' + sensor_attr->index;
756 newkey[2] = FAN_POSITION[2];
757 newkey[3] = FAN_POSITION[3];
758 newkey[4] = 0;
760 mutex_lock(&applesmc_lock);
762 ret = applesmc_read_key(newkey, buffer, 16);
763 buffer[16] = 0;
765 mutex_unlock(&applesmc_lock);
766 if (ret)
767 return ret;
768 else
769 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
772 static ssize_t applesmc_calibrate_show(struct device *dev,
773 struct device_attribute *attr, char *sysfsbuf)
775 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
778 static ssize_t applesmc_calibrate_store(struct device *dev,
779 struct device_attribute *attr, const char *sysfsbuf, size_t count)
781 mutex_lock(&applesmc_lock);
782 applesmc_calibrate();
783 mutex_unlock(&applesmc_lock);
785 return count;
788 /* Store the next backlight value to be written by the work */
789 static unsigned int backlight_value;
791 static void applesmc_backlight_set(struct work_struct *work)
793 u8 buffer[2];
795 mutex_lock(&applesmc_lock);
796 buffer[0] = backlight_value;
797 buffer[1] = 0x00;
798 applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
799 mutex_unlock(&applesmc_lock);
801 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
803 static void applesmc_brightness_set(struct led_classdev *led_cdev,
804 enum led_brightness value)
806 int ret;
808 backlight_value = value;
809 ret = queue_work(applesmc_led_wq, &backlight_work);
811 if (debug && (!ret))
812 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
815 static ssize_t applesmc_key_count_show(struct device *dev,
816 struct device_attribute *attr, char *sysfsbuf)
818 int ret;
819 u8 buffer[4];
820 u32 count;
822 mutex_lock(&applesmc_lock);
824 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
825 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
826 ((u32)buffer[2]<<8) + buffer[3];
828 mutex_unlock(&applesmc_lock);
829 if (ret)
830 return ret;
831 else
832 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
835 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
836 struct device_attribute *attr, char *sysfsbuf)
838 char key[5];
839 char info[6];
840 int ret;
842 mutex_lock(&applesmc_lock);
844 ret = applesmc_get_key_at_index(key_at_index, key);
846 if (ret || !key[0]) {
847 mutex_unlock(&applesmc_lock);
849 return -EINVAL;
852 ret = applesmc_get_key_type(key, info);
854 if (ret) {
855 mutex_unlock(&applesmc_lock);
857 return ret;
861 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
862 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
864 ret = applesmc_read_key(key, sysfsbuf, info[0]);
866 mutex_unlock(&applesmc_lock);
868 if (!ret) {
869 return info[0];
870 } else {
871 return ret;
875 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
876 struct device_attribute *attr, char *sysfsbuf)
878 char key[5];
879 char info[6];
880 int ret;
882 mutex_lock(&applesmc_lock);
884 ret = applesmc_get_key_at_index(key_at_index, key);
886 if (ret || !key[0]) {
887 mutex_unlock(&applesmc_lock);
889 return -EINVAL;
892 ret = applesmc_get_key_type(key, info);
894 mutex_unlock(&applesmc_lock);
896 if (!ret)
897 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
898 else
899 return ret;
902 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
903 struct device_attribute *attr, char *sysfsbuf)
905 char key[5];
906 char info[6];
907 int ret;
909 mutex_lock(&applesmc_lock);
911 ret = applesmc_get_key_at_index(key_at_index, key);
913 if (ret || !key[0]) {
914 mutex_unlock(&applesmc_lock);
916 return -EINVAL;
919 ret = applesmc_get_key_type(key, info);
921 mutex_unlock(&applesmc_lock);
923 if (!ret)
924 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
925 else
926 return ret;
929 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
930 struct device_attribute *attr, char *sysfsbuf)
932 char key[5];
933 int ret;
935 mutex_lock(&applesmc_lock);
937 ret = applesmc_get_key_at_index(key_at_index, key);
939 mutex_unlock(&applesmc_lock);
941 if (!ret && key[0])
942 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
943 else
944 return -EINVAL;
947 static ssize_t applesmc_key_at_index_show(struct device *dev,
948 struct device_attribute *attr, char *sysfsbuf)
950 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
953 static ssize_t applesmc_key_at_index_store(struct device *dev,
954 struct device_attribute *attr, const char *sysfsbuf, size_t count)
956 mutex_lock(&applesmc_lock);
958 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
960 mutex_unlock(&applesmc_lock);
962 return count;
965 static struct led_classdev applesmc_backlight = {
966 .name = "smc::kbd_backlight",
967 .default_trigger = "nand-disk",
968 .brightness_set = applesmc_brightness_set,
971 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
973 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
974 static DEVICE_ATTR(calibrate, 0644,
975 applesmc_calibrate_show, applesmc_calibrate_store);
977 static struct attribute *accelerometer_attributes[] = {
978 &dev_attr_position.attr,
979 &dev_attr_calibrate.attr,
980 NULL
983 static const struct attribute_group accelerometer_attributes_group =
984 { .attrs = accelerometer_attributes };
986 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
988 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
989 static DEVICE_ATTR(key_at_index, 0644,
990 applesmc_key_at_index_show, applesmc_key_at_index_store);
991 static DEVICE_ATTR(key_at_index_name, 0444,
992 applesmc_key_at_index_name_show, NULL);
993 static DEVICE_ATTR(key_at_index_type, 0444,
994 applesmc_key_at_index_type_show, NULL);
995 static DEVICE_ATTR(key_at_index_data_length, 0444,
996 applesmc_key_at_index_data_length_show, NULL);
997 static DEVICE_ATTR(key_at_index_data, 0444,
998 applesmc_key_at_index_read_show, NULL);
1000 static struct attribute *key_enumeration_attributes[] = {
1001 &dev_attr_key_count.attr,
1002 &dev_attr_key_at_index.attr,
1003 &dev_attr_key_at_index_name.attr,
1004 &dev_attr_key_at_index_type.attr,
1005 &dev_attr_key_at_index_data_length.attr,
1006 &dev_attr_key_at_index_data.attr,
1007 NULL
1010 static const struct attribute_group key_enumeration_group =
1011 { .attrs = key_enumeration_attributes };
1014 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1015 * - show actual speed
1016 * - show/store minimum speed
1017 * - show maximum speed
1018 * - show safe speed
1019 * - show/store target speed
1020 * - show/store manual mode
1022 #define sysfs_fan_speeds_offset(offset) \
1023 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1024 applesmc_show_fan_speed, NULL, 0, offset-1); \
1026 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1027 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1029 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1030 applesmc_show_fan_speed, NULL, 2, offset-1); \
1032 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1033 applesmc_show_fan_speed, NULL, 3, offset-1); \
1035 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1036 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1038 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1039 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1041 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1042 applesmc_show_fan_position, NULL, offset-1); \
1044 static struct attribute *fan##offset##_attributes[] = { \
1045 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1046 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1047 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1048 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1049 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1050 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1051 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1052 NULL \
1056 * Create the needed functions for each fan using the macro defined above
1057 * (4 fans are supported)
1059 sysfs_fan_speeds_offset(1);
1060 sysfs_fan_speeds_offset(2);
1061 sysfs_fan_speeds_offset(3);
1062 sysfs_fan_speeds_offset(4);
1064 static const struct attribute_group fan_attribute_groups[] = {
1065 { .attrs = fan1_attributes },
1066 { .attrs = fan2_attributes },
1067 { .attrs = fan3_attributes },
1068 { .attrs = fan4_attributes },
1072 * Temperature sensors sysfs entries.
1074 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1075 applesmc_show_temperature, NULL, 0);
1076 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1077 applesmc_show_temperature, NULL, 1);
1078 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1079 applesmc_show_temperature, NULL, 2);
1080 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1081 applesmc_show_temperature, NULL, 3);
1082 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1083 applesmc_show_temperature, NULL, 4);
1084 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1085 applesmc_show_temperature, NULL, 5);
1086 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1087 applesmc_show_temperature, NULL, 6);
1088 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1089 applesmc_show_temperature, NULL, 7);
1090 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1091 applesmc_show_temperature, NULL, 8);
1092 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1093 applesmc_show_temperature, NULL, 9);
1094 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1095 applesmc_show_temperature, NULL, 10);
1096 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1097 applesmc_show_temperature, NULL, 11);
1098 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1099 applesmc_show_temperature, NULL, 12);
1100 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1101 applesmc_show_temperature, NULL, 13);
1102 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1103 applesmc_show_temperature, NULL, 14);
1104 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1105 applesmc_show_temperature, NULL, 15);
1106 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1107 applesmc_show_temperature, NULL, 16);
1108 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1109 applesmc_show_temperature, NULL, 17);
1110 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1111 applesmc_show_temperature, NULL, 18);
1112 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1113 applesmc_show_temperature, NULL, 19);
1114 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1115 applesmc_show_temperature, NULL, 20);
1116 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1117 applesmc_show_temperature, NULL, 21);
1118 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1119 applesmc_show_temperature, NULL, 22);
1120 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1121 applesmc_show_temperature, NULL, 23);
1122 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1123 applesmc_show_temperature, NULL, 24);
1124 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1125 applesmc_show_temperature, NULL, 25);
1126 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1127 applesmc_show_temperature, NULL, 26);
1128 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1129 applesmc_show_temperature, NULL, 27);
1130 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1131 applesmc_show_temperature, NULL, 28);
1132 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1133 applesmc_show_temperature, NULL, 29);
1134 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1135 applesmc_show_temperature, NULL, 30);
1136 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1137 applesmc_show_temperature, NULL, 31);
1138 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1139 applesmc_show_temperature, NULL, 32);
1140 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1141 applesmc_show_temperature, NULL, 33);
1142 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1143 applesmc_show_temperature, NULL, 34);
1145 static struct attribute *temperature_attributes[] = {
1146 &sensor_dev_attr_temp1_input.dev_attr.attr,
1147 &sensor_dev_attr_temp2_input.dev_attr.attr,
1148 &sensor_dev_attr_temp3_input.dev_attr.attr,
1149 &sensor_dev_attr_temp4_input.dev_attr.attr,
1150 &sensor_dev_attr_temp5_input.dev_attr.attr,
1151 &sensor_dev_attr_temp6_input.dev_attr.attr,
1152 &sensor_dev_attr_temp7_input.dev_attr.attr,
1153 &sensor_dev_attr_temp8_input.dev_attr.attr,
1154 &sensor_dev_attr_temp9_input.dev_attr.attr,
1155 &sensor_dev_attr_temp10_input.dev_attr.attr,
1156 &sensor_dev_attr_temp11_input.dev_attr.attr,
1157 &sensor_dev_attr_temp12_input.dev_attr.attr,
1158 &sensor_dev_attr_temp13_input.dev_attr.attr,
1159 &sensor_dev_attr_temp14_input.dev_attr.attr,
1160 &sensor_dev_attr_temp15_input.dev_attr.attr,
1161 &sensor_dev_attr_temp16_input.dev_attr.attr,
1162 &sensor_dev_attr_temp17_input.dev_attr.attr,
1163 &sensor_dev_attr_temp18_input.dev_attr.attr,
1164 &sensor_dev_attr_temp19_input.dev_attr.attr,
1165 &sensor_dev_attr_temp20_input.dev_attr.attr,
1166 &sensor_dev_attr_temp21_input.dev_attr.attr,
1167 &sensor_dev_attr_temp22_input.dev_attr.attr,
1168 &sensor_dev_attr_temp23_input.dev_attr.attr,
1169 &sensor_dev_attr_temp24_input.dev_attr.attr,
1170 &sensor_dev_attr_temp25_input.dev_attr.attr,
1171 &sensor_dev_attr_temp26_input.dev_attr.attr,
1172 &sensor_dev_attr_temp27_input.dev_attr.attr,
1173 &sensor_dev_attr_temp28_input.dev_attr.attr,
1174 &sensor_dev_attr_temp29_input.dev_attr.attr,
1175 &sensor_dev_attr_temp30_input.dev_attr.attr,
1176 &sensor_dev_attr_temp31_input.dev_attr.attr,
1177 &sensor_dev_attr_temp32_input.dev_attr.attr,
1178 &sensor_dev_attr_temp33_input.dev_attr.attr,
1179 &sensor_dev_attr_temp34_input.dev_attr.attr,
1180 &sensor_dev_attr_temp35_input.dev_attr.attr,
1181 NULL
1184 static const struct attribute_group temperature_attributes_group =
1185 { .attrs = temperature_attributes };
1187 /* Module stuff */
1190 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1192 static int applesmc_dmi_match(const struct dmi_system_id *id)
1194 int i = 0;
1195 struct dmi_match_data* dmi_data = id->driver_data;
1196 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1197 applesmc_accelerometer = dmi_data->accelerometer;
1198 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1199 applesmc_accelerometer ? "with" : "without");
1200 applesmc_light = dmi_data->light;
1201 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1202 applesmc_light ? "with" : "without");
1204 applesmc_temperature_set = dmi_data->temperature_set;
1205 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1206 i++;
1207 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1208 return 1;
1211 /* Create accelerometer ressources */
1212 static int applesmc_create_accelerometer(void)
1214 struct input_dev *idev;
1215 int ret;
1217 ret = sysfs_create_group(&pdev->dev.kobj,
1218 &accelerometer_attributes_group);
1219 if (ret)
1220 goto out;
1222 applesmc_idev = input_allocate_polled_device();
1223 if (!applesmc_idev) {
1224 ret = -ENOMEM;
1225 goto out_sysfs;
1228 applesmc_idev->poll = applesmc_idev_poll;
1229 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1231 /* initial calibrate for the input device */
1232 applesmc_calibrate();
1234 /* initialize the input device */
1235 idev = applesmc_idev->input;
1236 idev->name = "applesmc";
1237 idev->id.bustype = BUS_HOST;
1238 idev->dev.parent = &pdev->dev;
1239 idev->evbit[0] = BIT_MASK(EV_ABS);
1240 input_set_abs_params(idev, ABS_X,
1241 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1242 input_set_abs_params(idev, ABS_Y,
1243 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1245 ret = input_register_polled_device(applesmc_idev);
1246 if (ret)
1247 goto out_idev;
1249 return 0;
1251 out_idev:
1252 input_free_polled_device(applesmc_idev);
1254 out_sysfs:
1255 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1257 out:
1258 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1259 return ret;
1262 /* Release all ressources used by the accelerometer */
1263 static void applesmc_release_accelerometer(void)
1265 input_unregister_polled_device(applesmc_idev);
1266 input_free_polled_device(applesmc_idev);
1267 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1270 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1271 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1272 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1273 /* MacBook2: accelerometer and temperature set 1 */
1274 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1275 /* MacBook: accelerometer and temperature set 2 */
1276 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1277 /* MacMini: temperature set 3 */
1278 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1279 /* MacPro: temperature set 4 */
1280 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1281 /* iMac: temperature set 5 */
1282 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1283 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1284 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1285 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1286 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1287 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1288 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1289 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1290 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1291 /* iMac 5: light sensor only, temperature set 10 */
1292 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1293 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1294 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
1295 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1296 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
1297 /* iMac 8: light sensor only, temperature set 13 */
1298 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
1301 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1302 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1303 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1304 { applesmc_dmi_match, "Apple MacBook Air", {
1305 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1306 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1307 &applesmc_dmi_data[7]},
1308 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1309 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1310 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1311 &applesmc_dmi_data[12]},
1312 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1313 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1314 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1315 &applesmc_dmi_data[8]},
1316 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1317 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1318 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1319 &applesmc_dmi_data[9]},
1320 { applesmc_dmi_match, "Apple MacBook Pro", {
1321 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1322 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1323 &applesmc_dmi_data[0]},
1324 { applesmc_dmi_match, "Apple MacBook (v2)", {
1325 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1326 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1327 &applesmc_dmi_data[1]},
1328 { applesmc_dmi_match, "Apple MacBook (v3)", {
1329 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1330 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1331 &applesmc_dmi_data[6]},
1332 { applesmc_dmi_match, "Apple MacBook 4", {
1333 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1334 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1335 &applesmc_dmi_data[6]},
1336 { applesmc_dmi_match, "Apple MacBook 5", {
1337 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1338 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1339 &applesmc_dmi_data[11]},
1340 { applesmc_dmi_match, "Apple MacBook", {
1341 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1342 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1343 &applesmc_dmi_data[2]},
1344 { applesmc_dmi_match, "Apple Macmini", {
1345 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1346 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1347 &applesmc_dmi_data[3]},
1348 { applesmc_dmi_match, "Apple MacPro2", {
1349 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1350 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1351 &applesmc_dmi_data[4]},
1352 { applesmc_dmi_match, "Apple iMac 8", {
1353 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1354 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1355 &applesmc_dmi_data[13]},
1356 { applesmc_dmi_match, "Apple iMac 5", {
1357 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1358 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1359 &applesmc_dmi_data[10]},
1360 { applesmc_dmi_match, "Apple iMac", {
1361 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1362 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1363 &applesmc_dmi_data[5]},
1364 { .ident = NULL }
1367 static int __init applesmc_init(void)
1369 int ret;
1370 int count;
1371 int i;
1373 if (!dmi_check_system(applesmc_whitelist)) {
1374 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1375 ret = -ENODEV;
1376 goto out;
1379 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1380 "applesmc")) {
1381 ret = -ENXIO;
1382 goto out;
1385 ret = platform_driver_register(&applesmc_driver);
1386 if (ret)
1387 goto out_region;
1389 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1390 NULL, 0);
1391 if (IS_ERR(pdev)) {
1392 ret = PTR_ERR(pdev);
1393 goto out_driver;
1396 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1397 if (ret)
1398 goto out_device;
1400 /* Create key enumeration sysfs files */
1401 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1402 if (ret)
1403 goto out_name;
1405 /* create fan files */
1406 count = applesmc_get_fan_count();
1407 if (count < 0) {
1408 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1409 } else {
1410 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1412 switch (count) {
1413 default:
1414 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1415 " but at most 4 fans are supported"
1416 " by the driver.\n");
1417 case 4:
1418 ret = sysfs_create_group(&pdev->dev.kobj,
1419 &fan_attribute_groups[3]);
1420 if (ret)
1421 goto out_key_enumeration;
1422 case 3:
1423 ret = sysfs_create_group(&pdev->dev.kobj,
1424 &fan_attribute_groups[2]);
1425 if (ret)
1426 goto out_key_enumeration;
1427 case 2:
1428 ret = sysfs_create_group(&pdev->dev.kobj,
1429 &fan_attribute_groups[1]);
1430 if (ret)
1431 goto out_key_enumeration;
1432 case 1:
1433 ret = sysfs_create_group(&pdev->dev.kobj,
1434 &fan_attribute_groups[0]);
1435 if (ret)
1436 goto out_fan_1;
1437 case 0:
1442 for (i = 0;
1443 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1444 i++) {
1445 if (temperature_attributes[i] == NULL) {
1446 printk(KERN_ERR "applesmc: More temperature sensors "
1447 "in temperature_sensors_sets (at least %i)"
1448 "than available sysfs files in "
1449 "temperature_attributes (%i), please report "
1450 "this bug.\n", i, i-1);
1451 goto out_temperature;
1453 ret = sysfs_create_file(&pdev->dev.kobj,
1454 temperature_attributes[i]);
1455 if (ret)
1456 goto out_temperature;
1459 if (applesmc_accelerometer) {
1460 ret = applesmc_create_accelerometer();
1461 if (ret)
1462 goto out_temperature;
1465 if (applesmc_light) {
1466 /* Add light sensor file */
1467 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1468 if (ret)
1469 goto out_accelerometer;
1471 /* Create the workqueue */
1472 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1473 if (!applesmc_led_wq) {
1474 ret = -ENOMEM;
1475 goto out_light_sysfs;
1478 /* register as a led device */
1479 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1480 if (ret < 0)
1481 goto out_light_wq;
1484 hwmon_dev = hwmon_device_register(&pdev->dev);
1485 if (IS_ERR(hwmon_dev)) {
1486 ret = PTR_ERR(hwmon_dev);
1487 goto out_light_ledclass;
1490 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1492 return 0;
1494 out_light_ledclass:
1495 if (applesmc_light)
1496 led_classdev_unregister(&applesmc_backlight);
1497 out_light_wq:
1498 if (applesmc_light)
1499 destroy_workqueue(applesmc_led_wq);
1500 out_light_sysfs:
1501 if (applesmc_light)
1502 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1503 out_accelerometer:
1504 if (applesmc_accelerometer)
1505 applesmc_release_accelerometer();
1506 out_temperature:
1507 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1508 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1509 out_fan_1:
1510 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1511 out_key_enumeration:
1512 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1513 out_name:
1514 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1515 out_device:
1516 platform_device_unregister(pdev);
1517 out_driver:
1518 platform_driver_unregister(&applesmc_driver);
1519 out_region:
1520 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1521 out:
1522 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1523 return ret;
1526 static void __exit applesmc_exit(void)
1528 hwmon_device_unregister(hwmon_dev);
1529 if (applesmc_light) {
1530 led_classdev_unregister(&applesmc_backlight);
1531 destroy_workqueue(applesmc_led_wq);
1532 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1534 if (applesmc_accelerometer)
1535 applesmc_release_accelerometer();
1536 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1537 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1538 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1539 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1540 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1541 platform_device_unregister(pdev);
1542 platform_driver_unregister(&applesmc_driver);
1543 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1545 printk(KERN_INFO "applesmc: driver unloaded.\n");
1548 module_init(applesmc_init);
1549 module_exit(applesmc_exit);
1551 MODULE_AUTHOR("Nicolas Boichat");
1552 MODULE_DESCRIPTION("Apple SMC");
1553 MODULE_LICENSE("GPL v2");