hwmon: applesmc: add support for iMac 5
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / hwmon / applesmc.c
blob80d545d3aa12597e69f8cf317a4dc6398e98ff54
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 },
123 /* List of keys used to read/write fan speeds */
124 static const char* fan_speed_keys[] = {
125 FAN_ACTUAL_SPEED,
126 FAN_MIN_SPEED,
127 FAN_MAX_SPEED,
128 FAN_SAFE_SPEED,
129 FAN_TARGET_SPEED
132 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
133 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
135 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
136 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
137 #define APPLESMC_INPUT_FLAT 4
139 #define SENSOR_X 0
140 #define SENSOR_Y 1
141 #define SENSOR_Z 2
143 /* Structure to be passed to DMI_MATCH function */
144 struct dmi_match_data {
145 /* Indicates whether this computer has an accelerometer. */
146 int accelerometer;
147 /* Indicates whether this computer has light sensors and keyboard backlight. */
148 int light;
149 /* Indicates which temperature sensors set to use. */
150 int temperature_set;
153 static const int debug;
154 static struct platform_device *pdev;
155 static s16 rest_x;
156 static s16 rest_y;
157 static struct device *hwmon_dev;
158 static struct input_polled_dev *applesmc_idev;
160 /* Indicates whether this computer has an accelerometer. */
161 static unsigned int applesmc_accelerometer;
163 /* Indicates whether this computer has light sensors and keyboard backlight. */
164 static unsigned int applesmc_light;
166 /* Indicates which temperature sensors set to use. */
167 static unsigned int applesmc_temperature_set;
169 static DEFINE_MUTEX(applesmc_lock);
172 * Last index written to key_at_index sysfs file, and value to use for all other
173 * key_at_index_* sysfs files.
175 static unsigned int key_at_index;
177 static struct workqueue_struct *applesmc_led_wq;
180 * __wait_status - Wait up to 32ms for the status port to get a certain value
181 * (masked with 0x0f), returning zero if the value is obtained. Callers must
182 * hold applesmc_lock.
184 static int __wait_status(u8 val)
186 int us;
188 val = val & APPLESMC_STATUS_MASK;
190 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
191 udelay(us);
192 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
193 if (debug)
194 printk(KERN_DEBUG
195 "Waited %d us for status %x\n",
196 2 * us - APPLESMC_MIN_WAIT, val);
197 return 0;
201 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
202 val, inb(APPLESMC_CMD_PORT));
204 return -EIO;
208 * special treatment of command port - on newer macbooks, it seems necessary
209 * to resend the command byte before polling the status again. Callers must
210 * hold applesmc_lock.
212 static int send_command(u8 cmd)
214 int us;
215 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
216 outb(cmd, APPLESMC_CMD_PORT);
217 udelay(us);
218 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
219 return 0;
221 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
222 cmd, inb(APPLESMC_CMD_PORT));
223 return -EIO;
227 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
228 * Returns zero on success or a negative error on failure. Callers must
229 * hold applesmc_lock.
231 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
233 int i;
235 if (len > APPLESMC_MAX_DATA_LENGTH) {
236 printk(KERN_ERR "applesmc_read_key: cannot read more than "
237 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
238 return -EINVAL;
241 if (send_command(APPLESMC_READ_CMD))
242 return -EIO;
244 for (i = 0; i < 4; i++) {
245 outb(key[i], APPLESMC_DATA_PORT);
246 if (__wait_status(0x04))
247 return -EIO;
249 if (debug)
250 printk(KERN_DEBUG "<%s", key);
252 outb(len, APPLESMC_DATA_PORT);
253 if (debug)
254 printk(KERN_DEBUG ">%x", len);
256 for (i = 0; i < len; i++) {
257 if (__wait_status(0x05))
258 return -EIO;
259 buffer[i] = inb(APPLESMC_DATA_PORT);
260 if (debug)
261 printk(KERN_DEBUG "<%x", buffer[i]);
263 if (debug)
264 printk(KERN_DEBUG "\n");
266 return 0;
270 * applesmc_write_key - writes len bytes from buffer to a given key.
271 * Returns zero on success or a negative error on failure. Callers must
272 * hold applesmc_lock.
274 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
276 int i;
278 if (len > APPLESMC_MAX_DATA_LENGTH) {
279 printk(KERN_ERR "applesmc_write_key: cannot write more than "
280 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
281 return -EINVAL;
284 if (send_command(APPLESMC_WRITE_CMD))
285 return -EIO;
287 for (i = 0; i < 4; i++) {
288 outb(key[i], APPLESMC_DATA_PORT);
289 if (__wait_status(0x04))
290 return -EIO;
293 outb(len, APPLESMC_DATA_PORT);
295 for (i = 0; i < len; i++) {
296 if (__wait_status(0x04))
297 return -EIO;
298 outb(buffer[i], APPLESMC_DATA_PORT);
301 return 0;
305 * applesmc_get_key_at_index - get key at index, and put the result in key
306 * (char[6]). Returns zero on success or a negative error on failure. Callers
307 * must hold applesmc_lock.
309 static int applesmc_get_key_at_index(int index, char* key)
311 int i;
312 u8 readkey[4];
313 readkey[0] = index >> 24;
314 readkey[1] = index >> 16;
315 readkey[2] = index >> 8;
316 readkey[3] = index;
318 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
319 return -EIO;
321 for (i = 0; i < 4; i++) {
322 outb(readkey[i], APPLESMC_DATA_PORT);
323 if (__wait_status(0x04))
324 return -EIO;
327 outb(4, APPLESMC_DATA_PORT);
329 for (i = 0; i < 4; i++) {
330 if (__wait_status(0x05))
331 return -EIO;
332 key[i] = inb(APPLESMC_DATA_PORT);
334 key[4] = 0;
336 return 0;
340 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
341 * Returns zero on success or a negative error on failure. Callers must
342 * hold applesmc_lock.
344 static int applesmc_get_key_type(char* key, char* type)
346 int i;
348 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
349 return -EIO;
351 for (i = 0; i < 4; i++) {
352 outb(key[i], APPLESMC_DATA_PORT);
353 if (__wait_status(0x04))
354 return -EIO;
357 outb(6, APPLESMC_DATA_PORT);
359 for (i = 0; i < 6; i++) {
360 if (__wait_status(0x05))
361 return -EIO;
362 type[i] = inb(APPLESMC_DATA_PORT);
364 type[5] = 0;
366 return 0;
370 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
371 * hold applesmc_lock.
373 static int applesmc_read_motion_sensor(int index, s16* value)
375 u8 buffer[2];
376 int ret;
378 switch (index) {
379 case SENSOR_X:
380 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
381 break;
382 case SENSOR_Y:
383 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
384 break;
385 case SENSOR_Z:
386 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
387 break;
388 default:
389 ret = -EINVAL;
392 *value = ((s16)buffer[0] << 8) | buffer[1];
394 return ret;
398 * applesmc_device_init - initialize the accelerometer. Returns zero on success
399 * and negative error code on failure. Can sleep.
401 static int applesmc_device_init(void)
403 int total, ret = -ENXIO;
404 u8 buffer[2];
406 if (!applesmc_accelerometer)
407 return 0;
409 mutex_lock(&applesmc_lock);
411 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
412 if (debug)
413 printk(KERN_DEBUG "applesmc try %d\n", total);
414 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
415 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
416 if (total == INIT_TIMEOUT_MSECS) {
417 printk(KERN_DEBUG "applesmc: device has"
418 " already been initialized"
419 " (0x%02x, 0x%02x).\n",
420 buffer[0], buffer[1]);
421 } else {
422 printk(KERN_DEBUG "applesmc: device"
423 " successfully initialized"
424 " (0x%02x, 0x%02x).\n",
425 buffer[0], buffer[1]);
427 ret = 0;
428 goto out;
430 buffer[0] = 0xe0;
431 buffer[1] = 0x00;
432 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
433 msleep(INIT_WAIT_MSECS);
436 printk(KERN_WARNING "applesmc: failed to init the device\n");
438 out:
439 mutex_unlock(&applesmc_lock);
440 return ret;
444 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
445 * applesmc_lock.
447 static int applesmc_get_fan_count(void)
449 int ret;
450 u8 buffer[1];
452 mutex_lock(&applesmc_lock);
454 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
456 mutex_unlock(&applesmc_lock);
457 if (ret)
458 return ret;
459 else
460 return buffer[0];
463 /* Device model stuff */
464 static int applesmc_probe(struct platform_device *dev)
466 int ret;
468 ret = applesmc_device_init();
469 if (ret)
470 return ret;
472 printk(KERN_INFO "applesmc: device successfully initialized.\n");
473 return 0;
476 static int applesmc_resume(struct platform_device *dev)
478 return applesmc_device_init();
481 static struct platform_driver applesmc_driver = {
482 .probe = applesmc_probe,
483 .resume = applesmc_resume,
484 .driver = {
485 .name = "applesmc",
486 .owner = THIS_MODULE,
491 * applesmc_calibrate - Set our "resting" values. Callers must
492 * hold applesmc_lock.
494 static void applesmc_calibrate(void)
496 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
497 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
498 rest_x = -rest_x;
501 static void applesmc_idev_poll(struct input_polled_dev *dev)
503 struct input_dev *idev = dev->input;
504 s16 x, y;
506 mutex_lock(&applesmc_lock);
508 if (applesmc_read_motion_sensor(SENSOR_X, &x))
509 goto out;
510 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
511 goto out;
513 x = -x;
514 input_report_abs(idev, ABS_X, x - rest_x);
515 input_report_abs(idev, ABS_Y, y - rest_y);
516 input_sync(idev);
518 out:
519 mutex_unlock(&applesmc_lock);
522 /* Sysfs Files */
524 static ssize_t applesmc_name_show(struct device *dev,
525 struct device_attribute *attr, char *buf)
527 return snprintf(buf, PAGE_SIZE, "applesmc\n");
530 static ssize_t applesmc_position_show(struct device *dev,
531 struct device_attribute *attr, char *buf)
533 int ret;
534 s16 x, y, z;
536 mutex_lock(&applesmc_lock);
538 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
539 if (ret)
540 goto out;
541 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
542 if (ret)
543 goto out;
544 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
545 if (ret)
546 goto out;
548 out:
549 mutex_unlock(&applesmc_lock);
550 if (ret)
551 return ret;
552 else
553 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
556 static ssize_t applesmc_light_show(struct device *dev,
557 struct device_attribute *attr, char *sysfsbuf)
559 static int data_length;
560 int ret;
561 u8 left = 0, right = 0;
562 u8 buffer[10], query[6];
564 mutex_lock(&applesmc_lock);
566 if (!data_length) {
567 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
568 if (ret)
569 goto out;
570 data_length = clamp_val(query[0], 0, 10);
571 printk(KERN_INFO "applesmc: light sensor data length set to "
572 "%d\n", data_length);
575 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
576 left = buffer[2];
577 if (ret)
578 goto out;
579 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
580 right = buffer[2];
582 out:
583 mutex_unlock(&applesmc_lock);
584 if (ret)
585 return ret;
586 else
587 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
590 /* Displays degree Celsius * 1000 */
591 static ssize_t applesmc_show_temperature(struct device *dev,
592 struct device_attribute *devattr, char *sysfsbuf)
594 int ret;
595 u8 buffer[2];
596 unsigned int temp;
597 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
598 const char* key =
599 temperature_sensors_sets[applesmc_temperature_set][attr->index];
601 mutex_lock(&applesmc_lock);
603 ret = applesmc_read_key(key, buffer, 2);
604 temp = buffer[0]*1000;
605 temp += (buffer[1] >> 6) * 250;
607 mutex_unlock(&applesmc_lock);
609 if (ret)
610 return ret;
611 else
612 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
615 static ssize_t applesmc_show_fan_speed(struct device *dev,
616 struct device_attribute *attr, char *sysfsbuf)
618 int ret;
619 unsigned int speed = 0;
620 char newkey[5];
621 u8 buffer[2];
622 struct sensor_device_attribute_2 *sensor_attr =
623 to_sensor_dev_attr_2(attr);
625 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
626 newkey[1] = '0' + sensor_attr->index;
627 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
628 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
629 newkey[4] = 0;
631 mutex_lock(&applesmc_lock);
633 ret = applesmc_read_key(newkey, buffer, 2);
634 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
636 mutex_unlock(&applesmc_lock);
637 if (ret)
638 return ret;
639 else
640 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
643 static ssize_t applesmc_store_fan_speed(struct device *dev,
644 struct device_attribute *attr,
645 const char *sysfsbuf, size_t count)
647 int ret;
648 u32 speed;
649 char newkey[5];
650 u8 buffer[2];
651 struct sensor_device_attribute_2 *sensor_attr =
652 to_sensor_dev_attr_2(attr);
654 speed = simple_strtoul(sysfsbuf, NULL, 10);
656 if (speed > 0x4000) /* Bigger than a 14-bit value */
657 return -EINVAL;
659 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
660 newkey[1] = '0' + sensor_attr->index;
661 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
662 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
663 newkey[4] = 0;
665 mutex_lock(&applesmc_lock);
667 buffer[0] = (speed >> 6) & 0xff;
668 buffer[1] = (speed << 2) & 0xff;
669 ret = applesmc_write_key(newkey, buffer, 2);
671 mutex_unlock(&applesmc_lock);
672 if (ret)
673 return ret;
674 else
675 return count;
678 static ssize_t applesmc_show_fan_manual(struct device *dev,
679 struct device_attribute *devattr, char *sysfsbuf)
681 int ret;
682 u16 manual = 0;
683 u8 buffer[2];
684 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
686 mutex_lock(&applesmc_lock);
688 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
689 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
691 mutex_unlock(&applesmc_lock);
692 if (ret)
693 return ret;
694 else
695 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
698 static ssize_t applesmc_store_fan_manual(struct device *dev,
699 struct device_attribute *devattr,
700 const char *sysfsbuf, size_t count)
702 int ret;
703 u8 buffer[2];
704 u32 input;
705 u16 val;
706 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
708 input = simple_strtoul(sysfsbuf, NULL, 10);
710 mutex_lock(&applesmc_lock);
712 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
713 val = (buffer[0] << 8 | buffer[1]);
714 if (ret)
715 goto out;
717 if (input)
718 val = val | (0x01 << attr->index);
719 else
720 val = val & ~(0x01 << attr->index);
722 buffer[0] = (val >> 8) & 0xFF;
723 buffer[1] = val & 0xFF;
725 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
727 out:
728 mutex_unlock(&applesmc_lock);
729 if (ret)
730 return ret;
731 else
732 return count;
735 static ssize_t applesmc_show_fan_position(struct device *dev,
736 struct device_attribute *attr, char *sysfsbuf)
738 int ret;
739 char newkey[5];
740 u8 buffer[17];
741 struct sensor_device_attribute_2 *sensor_attr =
742 to_sensor_dev_attr_2(attr);
744 newkey[0] = FAN_POSITION[0];
745 newkey[1] = '0' + sensor_attr->index;
746 newkey[2] = FAN_POSITION[2];
747 newkey[3] = FAN_POSITION[3];
748 newkey[4] = 0;
750 mutex_lock(&applesmc_lock);
752 ret = applesmc_read_key(newkey, buffer, 16);
753 buffer[16] = 0;
755 mutex_unlock(&applesmc_lock);
756 if (ret)
757 return ret;
758 else
759 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
762 static ssize_t applesmc_calibrate_show(struct device *dev,
763 struct device_attribute *attr, char *sysfsbuf)
765 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
768 static ssize_t applesmc_calibrate_store(struct device *dev,
769 struct device_attribute *attr, const char *sysfsbuf, size_t count)
771 mutex_lock(&applesmc_lock);
772 applesmc_calibrate();
773 mutex_unlock(&applesmc_lock);
775 return count;
778 /* Store the next backlight value to be written by the work */
779 static unsigned int backlight_value;
781 static void applesmc_backlight_set(struct work_struct *work)
783 u8 buffer[2];
785 mutex_lock(&applesmc_lock);
786 buffer[0] = backlight_value;
787 buffer[1] = 0x00;
788 applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
789 mutex_unlock(&applesmc_lock);
791 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
793 static void applesmc_brightness_set(struct led_classdev *led_cdev,
794 enum led_brightness value)
796 int ret;
798 backlight_value = value;
799 ret = queue_work(applesmc_led_wq, &backlight_work);
801 if (debug && (!ret))
802 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
805 static ssize_t applesmc_key_count_show(struct device *dev,
806 struct device_attribute *attr, char *sysfsbuf)
808 int ret;
809 u8 buffer[4];
810 u32 count;
812 mutex_lock(&applesmc_lock);
814 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
815 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
816 ((u32)buffer[2]<<8) + buffer[3];
818 mutex_unlock(&applesmc_lock);
819 if (ret)
820 return ret;
821 else
822 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
825 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
826 struct device_attribute *attr, char *sysfsbuf)
828 char key[5];
829 char info[6];
830 int ret;
832 mutex_lock(&applesmc_lock);
834 ret = applesmc_get_key_at_index(key_at_index, key);
836 if (ret || !key[0]) {
837 mutex_unlock(&applesmc_lock);
839 return -EINVAL;
842 ret = applesmc_get_key_type(key, info);
844 if (ret) {
845 mutex_unlock(&applesmc_lock);
847 return ret;
851 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
852 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
854 ret = applesmc_read_key(key, sysfsbuf, info[0]);
856 mutex_unlock(&applesmc_lock);
858 if (!ret) {
859 return info[0];
860 } else {
861 return ret;
865 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
866 struct device_attribute *attr, char *sysfsbuf)
868 char key[5];
869 char info[6];
870 int ret;
872 mutex_lock(&applesmc_lock);
874 ret = applesmc_get_key_at_index(key_at_index, key);
876 if (ret || !key[0]) {
877 mutex_unlock(&applesmc_lock);
879 return -EINVAL;
882 ret = applesmc_get_key_type(key, info);
884 mutex_unlock(&applesmc_lock);
886 if (!ret)
887 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
888 else
889 return ret;
892 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
893 struct device_attribute *attr, char *sysfsbuf)
895 char key[5];
896 char info[6];
897 int ret;
899 mutex_lock(&applesmc_lock);
901 ret = applesmc_get_key_at_index(key_at_index, key);
903 if (ret || !key[0]) {
904 mutex_unlock(&applesmc_lock);
906 return -EINVAL;
909 ret = applesmc_get_key_type(key, info);
911 mutex_unlock(&applesmc_lock);
913 if (!ret)
914 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
915 else
916 return ret;
919 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
920 struct device_attribute *attr, char *sysfsbuf)
922 char key[5];
923 int ret;
925 mutex_lock(&applesmc_lock);
927 ret = applesmc_get_key_at_index(key_at_index, key);
929 mutex_unlock(&applesmc_lock);
931 if (!ret && key[0])
932 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
933 else
934 return -EINVAL;
937 static ssize_t applesmc_key_at_index_show(struct device *dev,
938 struct device_attribute *attr, char *sysfsbuf)
940 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
943 static ssize_t applesmc_key_at_index_store(struct device *dev,
944 struct device_attribute *attr, const char *sysfsbuf, size_t count)
946 mutex_lock(&applesmc_lock);
948 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
950 mutex_unlock(&applesmc_lock);
952 return count;
955 static struct led_classdev applesmc_backlight = {
956 .name = "smc::kbd_backlight",
957 .default_trigger = "nand-disk",
958 .brightness_set = applesmc_brightness_set,
961 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
963 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
964 static DEVICE_ATTR(calibrate, 0644,
965 applesmc_calibrate_show, applesmc_calibrate_store);
967 static struct attribute *accelerometer_attributes[] = {
968 &dev_attr_position.attr,
969 &dev_attr_calibrate.attr,
970 NULL
973 static const struct attribute_group accelerometer_attributes_group =
974 { .attrs = accelerometer_attributes };
976 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
978 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
979 static DEVICE_ATTR(key_at_index, 0644,
980 applesmc_key_at_index_show, applesmc_key_at_index_store);
981 static DEVICE_ATTR(key_at_index_name, 0444,
982 applesmc_key_at_index_name_show, NULL);
983 static DEVICE_ATTR(key_at_index_type, 0444,
984 applesmc_key_at_index_type_show, NULL);
985 static DEVICE_ATTR(key_at_index_data_length, 0444,
986 applesmc_key_at_index_data_length_show, NULL);
987 static DEVICE_ATTR(key_at_index_data, 0444,
988 applesmc_key_at_index_read_show, NULL);
990 static struct attribute *key_enumeration_attributes[] = {
991 &dev_attr_key_count.attr,
992 &dev_attr_key_at_index.attr,
993 &dev_attr_key_at_index_name.attr,
994 &dev_attr_key_at_index_type.attr,
995 &dev_attr_key_at_index_data_length.attr,
996 &dev_attr_key_at_index_data.attr,
997 NULL
1000 static const struct attribute_group key_enumeration_group =
1001 { .attrs = key_enumeration_attributes };
1004 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1005 * - show actual speed
1006 * - show/store minimum speed
1007 * - show maximum speed
1008 * - show safe speed
1009 * - show/store target speed
1010 * - show/store manual mode
1012 #define sysfs_fan_speeds_offset(offset) \
1013 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1014 applesmc_show_fan_speed, NULL, 0, offset-1); \
1016 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1017 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1019 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1020 applesmc_show_fan_speed, NULL, 2, offset-1); \
1022 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1023 applesmc_show_fan_speed, NULL, 3, offset-1); \
1025 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1026 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1028 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1029 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1031 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1032 applesmc_show_fan_position, NULL, offset-1); \
1034 static struct attribute *fan##offset##_attributes[] = { \
1035 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1036 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1037 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1038 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1039 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1040 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1041 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1042 NULL \
1046 * Create the needed functions for each fan using the macro defined above
1047 * (4 fans are supported)
1049 sysfs_fan_speeds_offset(1);
1050 sysfs_fan_speeds_offset(2);
1051 sysfs_fan_speeds_offset(3);
1052 sysfs_fan_speeds_offset(4);
1054 static const struct attribute_group fan_attribute_groups[] = {
1055 { .attrs = fan1_attributes },
1056 { .attrs = fan2_attributes },
1057 { .attrs = fan3_attributes },
1058 { .attrs = fan4_attributes },
1062 * Temperature sensors sysfs entries.
1064 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1065 applesmc_show_temperature, NULL, 0);
1066 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1067 applesmc_show_temperature, NULL, 1);
1068 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1069 applesmc_show_temperature, NULL, 2);
1070 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1071 applesmc_show_temperature, NULL, 3);
1072 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1073 applesmc_show_temperature, NULL, 4);
1074 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1075 applesmc_show_temperature, NULL, 5);
1076 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1077 applesmc_show_temperature, NULL, 6);
1078 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1079 applesmc_show_temperature, NULL, 7);
1080 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1081 applesmc_show_temperature, NULL, 8);
1082 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1083 applesmc_show_temperature, NULL, 9);
1084 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1085 applesmc_show_temperature, NULL, 10);
1086 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1087 applesmc_show_temperature, NULL, 11);
1088 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1089 applesmc_show_temperature, NULL, 12);
1090 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1091 applesmc_show_temperature, NULL, 13);
1092 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1093 applesmc_show_temperature, NULL, 14);
1094 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1095 applesmc_show_temperature, NULL, 15);
1096 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1097 applesmc_show_temperature, NULL, 16);
1098 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1099 applesmc_show_temperature, NULL, 17);
1100 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1101 applesmc_show_temperature, NULL, 18);
1102 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1103 applesmc_show_temperature, NULL, 19);
1104 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1105 applesmc_show_temperature, NULL, 20);
1106 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1107 applesmc_show_temperature, NULL, 21);
1108 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1109 applesmc_show_temperature, NULL, 22);
1110 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1111 applesmc_show_temperature, NULL, 23);
1112 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1113 applesmc_show_temperature, NULL, 24);
1114 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1115 applesmc_show_temperature, NULL, 25);
1116 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1117 applesmc_show_temperature, NULL, 26);
1118 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1119 applesmc_show_temperature, NULL, 27);
1120 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1121 applesmc_show_temperature, NULL, 28);
1122 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1123 applesmc_show_temperature, NULL, 29);
1124 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1125 applesmc_show_temperature, NULL, 30);
1126 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1127 applesmc_show_temperature, NULL, 31);
1128 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1129 applesmc_show_temperature, NULL, 32);
1130 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1131 applesmc_show_temperature, NULL, 33);
1132 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1133 applesmc_show_temperature, NULL, 34);
1135 static struct attribute *temperature_attributes[] = {
1136 &sensor_dev_attr_temp1_input.dev_attr.attr,
1137 &sensor_dev_attr_temp2_input.dev_attr.attr,
1138 &sensor_dev_attr_temp3_input.dev_attr.attr,
1139 &sensor_dev_attr_temp4_input.dev_attr.attr,
1140 &sensor_dev_attr_temp5_input.dev_attr.attr,
1141 &sensor_dev_attr_temp6_input.dev_attr.attr,
1142 &sensor_dev_attr_temp7_input.dev_attr.attr,
1143 &sensor_dev_attr_temp8_input.dev_attr.attr,
1144 &sensor_dev_attr_temp9_input.dev_attr.attr,
1145 &sensor_dev_attr_temp10_input.dev_attr.attr,
1146 &sensor_dev_attr_temp11_input.dev_attr.attr,
1147 &sensor_dev_attr_temp12_input.dev_attr.attr,
1148 &sensor_dev_attr_temp13_input.dev_attr.attr,
1149 &sensor_dev_attr_temp14_input.dev_attr.attr,
1150 &sensor_dev_attr_temp15_input.dev_attr.attr,
1151 &sensor_dev_attr_temp16_input.dev_attr.attr,
1152 &sensor_dev_attr_temp17_input.dev_attr.attr,
1153 &sensor_dev_attr_temp18_input.dev_attr.attr,
1154 &sensor_dev_attr_temp19_input.dev_attr.attr,
1155 &sensor_dev_attr_temp20_input.dev_attr.attr,
1156 &sensor_dev_attr_temp21_input.dev_attr.attr,
1157 &sensor_dev_attr_temp22_input.dev_attr.attr,
1158 &sensor_dev_attr_temp23_input.dev_attr.attr,
1159 &sensor_dev_attr_temp24_input.dev_attr.attr,
1160 &sensor_dev_attr_temp25_input.dev_attr.attr,
1161 &sensor_dev_attr_temp26_input.dev_attr.attr,
1162 &sensor_dev_attr_temp27_input.dev_attr.attr,
1163 &sensor_dev_attr_temp28_input.dev_attr.attr,
1164 &sensor_dev_attr_temp29_input.dev_attr.attr,
1165 &sensor_dev_attr_temp30_input.dev_attr.attr,
1166 &sensor_dev_attr_temp31_input.dev_attr.attr,
1167 &sensor_dev_attr_temp32_input.dev_attr.attr,
1168 &sensor_dev_attr_temp33_input.dev_attr.attr,
1169 &sensor_dev_attr_temp34_input.dev_attr.attr,
1170 &sensor_dev_attr_temp35_input.dev_attr.attr,
1171 NULL
1174 static const struct attribute_group temperature_attributes_group =
1175 { .attrs = temperature_attributes };
1177 /* Module stuff */
1180 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1182 static int applesmc_dmi_match(const struct dmi_system_id *id)
1184 int i = 0;
1185 struct dmi_match_data* dmi_data = id->driver_data;
1186 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1187 applesmc_accelerometer = dmi_data->accelerometer;
1188 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1189 applesmc_accelerometer ? "with" : "without");
1190 applesmc_light = dmi_data->light;
1191 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1192 applesmc_light ? "with" : "without");
1194 applesmc_temperature_set = dmi_data->temperature_set;
1195 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1196 i++;
1197 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1198 return 1;
1201 /* Create accelerometer ressources */
1202 static int applesmc_create_accelerometer(void)
1204 struct input_dev *idev;
1205 int ret;
1207 ret = sysfs_create_group(&pdev->dev.kobj,
1208 &accelerometer_attributes_group);
1209 if (ret)
1210 goto out;
1212 applesmc_idev = input_allocate_polled_device();
1213 if (!applesmc_idev) {
1214 ret = -ENOMEM;
1215 goto out_sysfs;
1218 applesmc_idev->poll = applesmc_idev_poll;
1219 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1221 /* initial calibrate for the input device */
1222 applesmc_calibrate();
1224 /* initialize the input device */
1225 idev = applesmc_idev->input;
1226 idev->name = "applesmc";
1227 idev->id.bustype = BUS_HOST;
1228 idev->dev.parent = &pdev->dev;
1229 idev->evbit[0] = BIT_MASK(EV_ABS);
1230 input_set_abs_params(idev, ABS_X,
1231 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1232 input_set_abs_params(idev, ABS_Y,
1233 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1235 ret = input_register_polled_device(applesmc_idev);
1236 if (ret)
1237 goto out_idev;
1239 return 0;
1241 out_idev:
1242 input_free_polled_device(applesmc_idev);
1244 out_sysfs:
1245 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1247 out:
1248 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1249 return ret;
1252 /* Release all ressources used by the accelerometer */
1253 static void applesmc_release_accelerometer(void)
1255 input_unregister_polled_device(applesmc_idev);
1256 input_free_polled_device(applesmc_idev);
1257 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1260 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1261 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1262 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1263 /* MacBook2: accelerometer and temperature set 1 */
1264 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1265 /* MacBook: accelerometer and temperature set 2 */
1266 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1267 /* MacMini: temperature set 3 */
1268 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1269 /* MacPro: temperature set 4 */
1270 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1271 /* iMac: temperature set 5 */
1272 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1273 /* MacBook3: accelerometer and temperature set 6 */
1274 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1275 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1276 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1277 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1278 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1279 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1280 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1281 /* iMac 5: light sensor only, temperature set 10 */
1282 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1285 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1286 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1287 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1288 { applesmc_dmi_match, "Apple MacBook Air", {
1289 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1290 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1291 &applesmc_dmi_data[7]},
1292 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1293 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1294 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1295 &applesmc_dmi_data[8]},
1296 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1297 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1298 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1299 &applesmc_dmi_data[9]},
1300 { applesmc_dmi_match, "Apple MacBook Pro", {
1301 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1302 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1303 &applesmc_dmi_data[0]},
1304 { applesmc_dmi_match, "Apple MacBook (v2)", {
1305 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1306 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1307 &applesmc_dmi_data[1]},
1308 { applesmc_dmi_match, "Apple MacBook (v3)", {
1309 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1310 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1311 &applesmc_dmi_data[6]},
1312 { applesmc_dmi_match, "Apple MacBook", {
1313 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1314 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1315 &applesmc_dmi_data[2]},
1316 { applesmc_dmi_match, "Apple Macmini", {
1317 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1318 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1319 &applesmc_dmi_data[3]},
1320 { applesmc_dmi_match, "Apple MacPro2", {
1321 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1322 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1323 &applesmc_dmi_data[4]},
1324 { applesmc_dmi_match, "Apple iMac 5", {
1325 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1326 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1327 &applesmc_dmi_data[10]},
1328 { applesmc_dmi_match, "Apple iMac", {
1329 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1330 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1331 &applesmc_dmi_data[5]},
1332 { .ident = NULL }
1335 static int __init applesmc_init(void)
1337 int ret;
1338 int count;
1339 int i;
1341 if (!dmi_check_system(applesmc_whitelist)) {
1342 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1343 ret = -ENODEV;
1344 goto out;
1347 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1348 "applesmc")) {
1349 ret = -ENXIO;
1350 goto out;
1353 ret = platform_driver_register(&applesmc_driver);
1354 if (ret)
1355 goto out_region;
1357 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1358 NULL, 0);
1359 if (IS_ERR(pdev)) {
1360 ret = PTR_ERR(pdev);
1361 goto out_driver;
1364 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1365 if (ret)
1366 goto out_device;
1368 /* Create key enumeration sysfs files */
1369 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1370 if (ret)
1371 goto out_name;
1373 /* create fan files */
1374 count = applesmc_get_fan_count();
1375 if (count < 0) {
1376 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1377 } else {
1378 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1380 switch (count) {
1381 default:
1382 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1383 " but at most 4 fans are supported"
1384 " by the driver.\n");
1385 case 4:
1386 ret = sysfs_create_group(&pdev->dev.kobj,
1387 &fan_attribute_groups[3]);
1388 if (ret)
1389 goto out_key_enumeration;
1390 case 3:
1391 ret = sysfs_create_group(&pdev->dev.kobj,
1392 &fan_attribute_groups[2]);
1393 if (ret)
1394 goto out_key_enumeration;
1395 case 2:
1396 ret = sysfs_create_group(&pdev->dev.kobj,
1397 &fan_attribute_groups[1]);
1398 if (ret)
1399 goto out_key_enumeration;
1400 case 1:
1401 ret = sysfs_create_group(&pdev->dev.kobj,
1402 &fan_attribute_groups[0]);
1403 if (ret)
1404 goto out_fan_1;
1405 case 0:
1410 for (i = 0;
1411 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1412 i++) {
1413 if (temperature_attributes[i] == NULL) {
1414 printk(KERN_ERR "applesmc: More temperature sensors "
1415 "in temperature_sensors_sets (at least %i)"
1416 "than available sysfs files in "
1417 "temperature_attributes (%i), please report "
1418 "this bug.\n", i, i-1);
1419 goto out_temperature;
1421 ret = sysfs_create_file(&pdev->dev.kobj,
1422 temperature_attributes[i]);
1423 if (ret)
1424 goto out_temperature;
1427 if (applesmc_accelerometer) {
1428 ret = applesmc_create_accelerometer();
1429 if (ret)
1430 goto out_temperature;
1433 if (applesmc_light) {
1434 /* Add light sensor file */
1435 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1436 if (ret)
1437 goto out_accelerometer;
1439 /* Create the workqueue */
1440 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1441 if (!applesmc_led_wq) {
1442 ret = -ENOMEM;
1443 goto out_light_sysfs;
1446 /* register as a led device */
1447 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1448 if (ret < 0)
1449 goto out_light_wq;
1452 hwmon_dev = hwmon_device_register(&pdev->dev);
1453 if (IS_ERR(hwmon_dev)) {
1454 ret = PTR_ERR(hwmon_dev);
1455 goto out_light_ledclass;
1458 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1460 return 0;
1462 out_light_ledclass:
1463 if (applesmc_light)
1464 led_classdev_unregister(&applesmc_backlight);
1465 out_light_wq:
1466 if (applesmc_light)
1467 destroy_workqueue(applesmc_led_wq);
1468 out_light_sysfs:
1469 if (applesmc_light)
1470 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1471 out_accelerometer:
1472 if (applesmc_accelerometer)
1473 applesmc_release_accelerometer();
1474 out_temperature:
1475 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1476 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1477 out_fan_1:
1478 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1479 out_key_enumeration:
1480 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1481 out_name:
1482 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1483 out_device:
1484 platform_device_unregister(pdev);
1485 out_driver:
1486 platform_driver_unregister(&applesmc_driver);
1487 out_region:
1488 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1489 out:
1490 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1491 return ret;
1494 static void __exit applesmc_exit(void)
1496 hwmon_device_unregister(hwmon_dev);
1497 if (applesmc_light) {
1498 led_classdev_unregister(&applesmc_backlight);
1499 destroy_workqueue(applesmc_led_wq);
1500 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1502 if (applesmc_accelerometer)
1503 applesmc_release_accelerometer();
1504 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1505 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1506 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1507 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1508 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1509 platform_device_unregister(pdev);
1510 platform_driver_unregister(&applesmc_driver);
1511 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1513 printk(KERN_INFO "applesmc: driver unloaded.\n");
1516 module_init(applesmc_init);
1517 module_exit(applesmc_exit);
1519 MODULE_AUTHOR("Nicolas Boichat");
1520 MODULE_DESCRIPTION("Apple SMC");
1521 MODULE_LICENSE("GPL v2");