CRED: Wrap task credential accesses in the XFS filesystem
[linux-2.6/mini2440.git] / drivers / hwmon / applesmc.c
blobbc011da79e148249e24a1439e3c4cb55fcd1c7b0
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 },
121 /* List of keys used to read/write fan speeds */
122 static const char* fan_speed_keys[] = {
123 FAN_ACTUAL_SPEED,
124 FAN_MIN_SPEED,
125 FAN_MAX_SPEED,
126 FAN_SAFE_SPEED,
127 FAN_TARGET_SPEED
130 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
131 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
133 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
134 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
135 #define APPLESMC_INPUT_FLAT 4
137 #define SENSOR_X 0
138 #define SENSOR_Y 1
139 #define SENSOR_Z 2
141 /* Structure to be passed to DMI_MATCH function */
142 struct dmi_match_data {
143 /* Indicates whether this computer has an accelerometer. */
144 int accelerometer;
145 /* Indicates whether this computer has light sensors and keyboard backlight. */
146 int light;
147 /* Indicates which temperature sensors set to use. */
148 int temperature_set;
151 static const int debug;
152 static struct platform_device *pdev;
153 static s16 rest_x;
154 static s16 rest_y;
155 static struct device *hwmon_dev;
156 static struct input_polled_dev *applesmc_idev;
158 /* Indicates whether this computer has an accelerometer. */
159 static unsigned int applesmc_accelerometer;
161 /* Indicates whether this computer has light sensors and keyboard backlight. */
162 static unsigned int applesmc_light;
164 /* Indicates which temperature sensors set to use. */
165 static unsigned int applesmc_temperature_set;
167 static DEFINE_MUTEX(applesmc_lock);
170 * Last index written to key_at_index sysfs file, and value to use for all other
171 * key_at_index_* sysfs files.
173 static unsigned int key_at_index;
175 static struct workqueue_struct *applesmc_led_wq;
178 * __wait_status - Wait up to 32ms for the status port to get a certain value
179 * (masked with 0x0f), returning zero if the value is obtained. Callers must
180 * hold applesmc_lock.
182 static int __wait_status(u8 val)
184 int us;
186 val = val & APPLESMC_STATUS_MASK;
188 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
189 udelay(us);
190 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
191 if (debug)
192 printk(KERN_DEBUG
193 "Waited %d us for status %x\n",
194 2 * us - APPLESMC_MIN_WAIT, val);
195 return 0;
199 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
200 val, inb(APPLESMC_CMD_PORT));
202 return -EIO;
206 * special treatment of command port - on newer macbooks, it seems necessary
207 * to resend the command byte before polling the status again. Callers must
208 * hold applesmc_lock.
210 static int send_command(u8 cmd)
212 int us;
213 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
214 outb(cmd, APPLESMC_CMD_PORT);
215 udelay(us);
216 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
217 return 0;
219 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
220 cmd, inb(APPLESMC_CMD_PORT));
221 return -EIO;
225 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
226 * Returns zero on success or a negative error on failure. Callers must
227 * hold applesmc_lock.
229 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
231 int i;
233 if (len > APPLESMC_MAX_DATA_LENGTH) {
234 printk(KERN_ERR "applesmc_read_key: cannot read more than "
235 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
236 return -EINVAL;
239 if (send_command(APPLESMC_READ_CMD))
240 return -EIO;
242 for (i = 0; i < 4; i++) {
243 outb(key[i], APPLESMC_DATA_PORT);
244 if (__wait_status(0x04))
245 return -EIO;
247 if (debug)
248 printk(KERN_DEBUG "<%s", key);
250 outb(len, APPLESMC_DATA_PORT);
251 if (debug)
252 printk(KERN_DEBUG ">%x", len);
254 for (i = 0; i < len; i++) {
255 if (__wait_status(0x05))
256 return -EIO;
257 buffer[i] = inb(APPLESMC_DATA_PORT);
258 if (debug)
259 printk(KERN_DEBUG "<%x", buffer[i]);
261 if (debug)
262 printk(KERN_DEBUG "\n");
264 return 0;
268 * applesmc_write_key - writes len bytes from buffer to a given key.
269 * Returns zero on success or a negative error on failure. Callers must
270 * hold applesmc_lock.
272 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
274 int i;
276 if (len > APPLESMC_MAX_DATA_LENGTH) {
277 printk(KERN_ERR "applesmc_write_key: cannot write more than "
278 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
279 return -EINVAL;
282 if (send_command(APPLESMC_WRITE_CMD))
283 return -EIO;
285 for (i = 0; i < 4; i++) {
286 outb(key[i], APPLESMC_DATA_PORT);
287 if (__wait_status(0x04))
288 return -EIO;
291 outb(len, APPLESMC_DATA_PORT);
293 for (i = 0; i < len; i++) {
294 if (__wait_status(0x04))
295 return -EIO;
296 outb(buffer[i], APPLESMC_DATA_PORT);
299 return 0;
303 * applesmc_get_key_at_index - get key at index, and put the result in key
304 * (char[6]). Returns zero on success or a negative error on failure. Callers
305 * must hold applesmc_lock.
307 static int applesmc_get_key_at_index(int index, char* key)
309 int i;
310 u8 readkey[4];
311 readkey[0] = index >> 24;
312 readkey[1] = index >> 16;
313 readkey[2] = index >> 8;
314 readkey[3] = index;
316 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
317 return -EIO;
319 for (i = 0; i < 4; i++) {
320 outb(readkey[i], APPLESMC_DATA_PORT);
321 if (__wait_status(0x04))
322 return -EIO;
325 outb(4, APPLESMC_DATA_PORT);
327 for (i = 0; i < 4; i++) {
328 if (__wait_status(0x05))
329 return -EIO;
330 key[i] = inb(APPLESMC_DATA_PORT);
332 key[4] = 0;
334 return 0;
338 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
339 * Returns zero on success or a negative error on failure. Callers must
340 * hold applesmc_lock.
342 static int applesmc_get_key_type(char* key, char* type)
344 int i;
346 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
347 return -EIO;
349 for (i = 0; i < 4; i++) {
350 outb(key[i], APPLESMC_DATA_PORT);
351 if (__wait_status(0x04))
352 return -EIO;
355 outb(6, APPLESMC_DATA_PORT);
357 for (i = 0; i < 6; i++) {
358 if (__wait_status(0x05))
359 return -EIO;
360 type[i] = inb(APPLESMC_DATA_PORT);
362 type[5] = 0;
364 return 0;
368 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
369 * hold applesmc_lock.
371 static int applesmc_read_motion_sensor(int index, s16* value)
373 u8 buffer[2];
374 int ret;
376 switch (index) {
377 case SENSOR_X:
378 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
379 break;
380 case SENSOR_Y:
381 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
382 break;
383 case SENSOR_Z:
384 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
385 break;
386 default:
387 ret = -EINVAL;
390 *value = ((s16)buffer[0] << 8) | buffer[1];
392 return ret;
396 * applesmc_device_init - initialize the accelerometer. Returns zero on success
397 * and negative error code on failure. Can sleep.
399 static int applesmc_device_init(void)
401 int total, ret = -ENXIO;
402 u8 buffer[2];
404 if (!applesmc_accelerometer)
405 return 0;
407 mutex_lock(&applesmc_lock);
409 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
410 if (debug)
411 printk(KERN_DEBUG "applesmc try %d\n", total);
412 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
413 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
414 if (total == INIT_TIMEOUT_MSECS) {
415 printk(KERN_DEBUG "applesmc: device has"
416 " already been initialized"
417 " (0x%02x, 0x%02x).\n",
418 buffer[0], buffer[1]);
419 } else {
420 printk(KERN_DEBUG "applesmc: device"
421 " successfully initialized"
422 " (0x%02x, 0x%02x).\n",
423 buffer[0], buffer[1]);
425 ret = 0;
426 goto out;
428 buffer[0] = 0xe0;
429 buffer[1] = 0x00;
430 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
431 msleep(INIT_WAIT_MSECS);
434 printk(KERN_WARNING "applesmc: failed to init the device\n");
436 out:
437 mutex_unlock(&applesmc_lock);
438 return ret;
442 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
443 * applesmc_lock.
445 static int applesmc_get_fan_count(void)
447 int ret;
448 u8 buffer[1];
450 mutex_lock(&applesmc_lock);
452 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
454 mutex_unlock(&applesmc_lock);
455 if (ret)
456 return ret;
457 else
458 return buffer[0];
461 /* Device model stuff */
462 static int applesmc_probe(struct platform_device *dev)
464 int ret;
466 ret = applesmc_device_init();
467 if (ret)
468 return ret;
470 printk(KERN_INFO "applesmc: device successfully initialized.\n");
471 return 0;
474 static int applesmc_resume(struct platform_device *dev)
476 return applesmc_device_init();
479 static struct platform_driver applesmc_driver = {
480 .probe = applesmc_probe,
481 .resume = applesmc_resume,
482 .driver = {
483 .name = "applesmc",
484 .owner = THIS_MODULE,
489 * applesmc_calibrate - Set our "resting" values. Callers must
490 * hold applesmc_lock.
492 static void applesmc_calibrate(void)
494 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
495 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
496 rest_x = -rest_x;
499 static void applesmc_idev_poll(struct input_polled_dev *dev)
501 struct input_dev *idev = dev->input;
502 s16 x, y;
504 mutex_lock(&applesmc_lock);
506 if (applesmc_read_motion_sensor(SENSOR_X, &x))
507 goto out;
508 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
509 goto out;
511 x = -x;
512 input_report_abs(idev, ABS_X, x - rest_x);
513 input_report_abs(idev, ABS_Y, y - rest_y);
514 input_sync(idev);
516 out:
517 mutex_unlock(&applesmc_lock);
520 /* Sysfs Files */
522 static ssize_t applesmc_name_show(struct device *dev,
523 struct device_attribute *attr, char *buf)
525 return snprintf(buf, PAGE_SIZE, "applesmc\n");
528 static ssize_t applesmc_position_show(struct device *dev,
529 struct device_attribute *attr, char *buf)
531 int ret;
532 s16 x, y, z;
534 mutex_lock(&applesmc_lock);
536 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
537 if (ret)
538 goto out;
539 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
540 if (ret)
541 goto out;
542 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
543 if (ret)
544 goto out;
546 out:
547 mutex_unlock(&applesmc_lock);
548 if (ret)
549 return ret;
550 else
551 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
554 static ssize_t applesmc_light_show(struct device *dev,
555 struct device_attribute *attr, char *sysfsbuf)
557 static int data_length;
558 int ret;
559 u8 left = 0, right = 0;
560 u8 buffer[10], query[6];
562 mutex_lock(&applesmc_lock);
564 if (!data_length) {
565 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
566 if (ret)
567 goto out;
568 data_length = clamp_val(query[0], 0, 10);
569 printk(KERN_INFO "applesmc: light sensor data length set to "
570 "%d\n", data_length);
573 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
574 left = buffer[2];
575 if (ret)
576 goto out;
577 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
578 right = buffer[2];
580 out:
581 mutex_unlock(&applesmc_lock);
582 if (ret)
583 return ret;
584 else
585 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
588 /* Displays degree Celsius * 1000 */
589 static ssize_t applesmc_show_temperature(struct device *dev,
590 struct device_attribute *devattr, char *sysfsbuf)
592 int ret;
593 u8 buffer[2];
594 unsigned int temp;
595 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
596 const char* key =
597 temperature_sensors_sets[applesmc_temperature_set][attr->index];
599 mutex_lock(&applesmc_lock);
601 ret = applesmc_read_key(key, buffer, 2);
602 temp = buffer[0]*1000;
603 temp += (buffer[1] >> 6) * 250;
605 mutex_unlock(&applesmc_lock);
607 if (ret)
608 return ret;
609 else
610 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
613 static ssize_t applesmc_show_fan_speed(struct device *dev,
614 struct device_attribute *attr, char *sysfsbuf)
616 int ret;
617 unsigned int speed = 0;
618 char newkey[5];
619 u8 buffer[2];
620 struct sensor_device_attribute_2 *sensor_attr =
621 to_sensor_dev_attr_2(attr);
623 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
624 newkey[1] = '0' + sensor_attr->index;
625 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
626 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
627 newkey[4] = 0;
629 mutex_lock(&applesmc_lock);
631 ret = applesmc_read_key(newkey, buffer, 2);
632 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
634 mutex_unlock(&applesmc_lock);
635 if (ret)
636 return ret;
637 else
638 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
641 static ssize_t applesmc_store_fan_speed(struct device *dev,
642 struct device_attribute *attr,
643 const char *sysfsbuf, size_t count)
645 int ret;
646 u32 speed;
647 char newkey[5];
648 u8 buffer[2];
649 struct sensor_device_attribute_2 *sensor_attr =
650 to_sensor_dev_attr_2(attr);
652 speed = simple_strtoul(sysfsbuf, NULL, 10);
654 if (speed > 0x4000) /* Bigger than a 14-bit value */
655 return -EINVAL;
657 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
658 newkey[1] = '0' + sensor_attr->index;
659 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
660 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
661 newkey[4] = 0;
663 mutex_lock(&applesmc_lock);
665 buffer[0] = (speed >> 6) & 0xff;
666 buffer[1] = (speed << 2) & 0xff;
667 ret = applesmc_write_key(newkey, buffer, 2);
669 mutex_unlock(&applesmc_lock);
670 if (ret)
671 return ret;
672 else
673 return count;
676 static ssize_t applesmc_show_fan_manual(struct device *dev,
677 struct device_attribute *devattr, char *sysfsbuf)
679 int ret;
680 u16 manual = 0;
681 u8 buffer[2];
682 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
684 mutex_lock(&applesmc_lock);
686 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
687 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
689 mutex_unlock(&applesmc_lock);
690 if (ret)
691 return ret;
692 else
693 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
696 static ssize_t applesmc_store_fan_manual(struct device *dev,
697 struct device_attribute *devattr,
698 const char *sysfsbuf, size_t count)
700 int ret;
701 u8 buffer[2];
702 u32 input;
703 u16 val;
704 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
706 input = simple_strtoul(sysfsbuf, NULL, 10);
708 mutex_lock(&applesmc_lock);
710 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
711 val = (buffer[0] << 8 | buffer[1]);
712 if (ret)
713 goto out;
715 if (input)
716 val = val | (0x01 << attr->index);
717 else
718 val = val & ~(0x01 << attr->index);
720 buffer[0] = (val >> 8) & 0xFF;
721 buffer[1] = val & 0xFF;
723 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
725 out:
726 mutex_unlock(&applesmc_lock);
727 if (ret)
728 return ret;
729 else
730 return count;
733 static ssize_t applesmc_show_fan_position(struct device *dev,
734 struct device_attribute *attr, char *sysfsbuf)
736 int ret;
737 char newkey[5];
738 u8 buffer[17];
739 struct sensor_device_attribute_2 *sensor_attr =
740 to_sensor_dev_attr_2(attr);
742 newkey[0] = FAN_POSITION[0];
743 newkey[1] = '0' + sensor_attr->index;
744 newkey[2] = FAN_POSITION[2];
745 newkey[3] = FAN_POSITION[3];
746 newkey[4] = 0;
748 mutex_lock(&applesmc_lock);
750 ret = applesmc_read_key(newkey, buffer, 16);
751 buffer[16] = 0;
753 mutex_unlock(&applesmc_lock);
754 if (ret)
755 return ret;
756 else
757 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
760 static ssize_t applesmc_calibrate_show(struct device *dev,
761 struct device_attribute *attr, char *sysfsbuf)
763 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
766 static ssize_t applesmc_calibrate_store(struct device *dev,
767 struct device_attribute *attr, const char *sysfsbuf, size_t count)
769 mutex_lock(&applesmc_lock);
770 applesmc_calibrate();
771 mutex_unlock(&applesmc_lock);
773 return count;
776 /* Store the next backlight value to be written by the work */
777 static unsigned int backlight_value;
779 static void applesmc_backlight_set(struct work_struct *work)
781 u8 buffer[2];
783 mutex_lock(&applesmc_lock);
784 buffer[0] = backlight_value;
785 buffer[1] = 0x00;
786 applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
787 mutex_unlock(&applesmc_lock);
789 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
791 static void applesmc_brightness_set(struct led_classdev *led_cdev,
792 enum led_brightness value)
794 int ret;
796 backlight_value = value;
797 ret = queue_work(applesmc_led_wq, &backlight_work);
799 if (debug && (!ret))
800 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
803 static ssize_t applesmc_key_count_show(struct device *dev,
804 struct device_attribute *attr, char *sysfsbuf)
806 int ret;
807 u8 buffer[4];
808 u32 count;
810 mutex_lock(&applesmc_lock);
812 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
813 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
814 ((u32)buffer[2]<<8) + buffer[3];
816 mutex_unlock(&applesmc_lock);
817 if (ret)
818 return ret;
819 else
820 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
823 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
824 struct device_attribute *attr, char *sysfsbuf)
826 char key[5];
827 char info[6];
828 int ret;
830 mutex_lock(&applesmc_lock);
832 ret = applesmc_get_key_at_index(key_at_index, key);
834 if (ret || !key[0]) {
835 mutex_unlock(&applesmc_lock);
837 return -EINVAL;
840 ret = applesmc_get_key_type(key, info);
842 if (ret) {
843 mutex_unlock(&applesmc_lock);
845 return ret;
849 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
850 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
852 ret = applesmc_read_key(key, sysfsbuf, info[0]);
854 mutex_unlock(&applesmc_lock);
856 if (!ret) {
857 return info[0];
858 } else {
859 return ret;
863 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
864 struct device_attribute *attr, char *sysfsbuf)
866 char key[5];
867 char info[6];
868 int ret;
870 mutex_lock(&applesmc_lock);
872 ret = applesmc_get_key_at_index(key_at_index, key);
874 if (ret || !key[0]) {
875 mutex_unlock(&applesmc_lock);
877 return -EINVAL;
880 ret = applesmc_get_key_type(key, info);
882 mutex_unlock(&applesmc_lock);
884 if (!ret)
885 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
886 else
887 return ret;
890 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
891 struct device_attribute *attr, char *sysfsbuf)
893 char key[5];
894 char info[6];
895 int ret;
897 mutex_lock(&applesmc_lock);
899 ret = applesmc_get_key_at_index(key_at_index, key);
901 if (ret || !key[0]) {
902 mutex_unlock(&applesmc_lock);
904 return -EINVAL;
907 ret = applesmc_get_key_type(key, info);
909 mutex_unlock(&applesmc_lock);
911 if (!ret)
912 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
913 else
914 return ret;
917 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
918 struct device_attribute *attr, char *sysfsbuf)
920 char key[5];
921 int ret;
923 mutex_lock(&applesmc_lock);
925 ret = applesmc_get_key_at_index(key_at_index, key);
927 mutex_unlock(&applesmc_lock);
929 if (!ret && key[0])
930 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
931 else
932 return -EINVAL;
935 static ssize_t applesmc_key_at_index_show(struct device *dev,
936 struct device_attribute *attr, char *sysfsbuf)
938 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
941 static ssize_t applesmc_key_at_index_store(struct device *dev,
942 struct device_attribute *attr, const char *sysfsbuf, size_t count)
944 mutex_lock(&applesmc_lock);
946 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
948 mutex_unlock(&applesmc_lock);
950 return count;
953 static struct led_classdev applesmc_backlight = {
954 .name = "smc::kbd_backlight",
955 .default_trigger = "nand-disk",
956 .brightness_set = applesmc_brightness_set,
959 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
961 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
962 static DEVICE_ATTR(calibrate, 0644,
963 applesmc_calibrate_show, applesmc_calibrate_store);
965 static struct attribute *accelerometer_attributes[] = {
966 &dev_attr_position.attr,
967 &dev_attr_calibrate.attr,
968 NULL
971 static const struct attribute_group accelerometer_attributes_group =
972 { .attrs = accelerometer_attributes };
974 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
976 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
977 static DEVICE_ATTR(key_at_index, 0644,
978 applesmc_key_at_index_show, applesmc_key_at_index_store);
979 static DEVICE_ATTR(key_at_index_name, 0444,
980 applesmc_key_at_index_name_show, NULL);
981 static DEVICE_ATTR(key_at_index_type, 0444,
982 applesmc_key_at_index_type_show, NULL);
983 static DEVICE_ATTR(key_at_index_data_length, 0444,
984 applesmc_key_at_index_data_length_show, NULL);
985 static DEVICE_ATTR(key_at_index_data, 0444,
986 applesmc_key_at_index_read_show, NULL);
988 static struct attribute *key_enumeration_attributes[] = {
989 &dev_attr_key_count.attr,
990 &dev_attr_key_at_index.attr,
991 &dev_attr_key_at_index_name.attr,
992 &dev_attr_key_at_index_type.attr,
993 &dev_attr_key_at_index_data_length.attr,
994 &dev_attr_key_at_index_data.attr,
995 NULL
998 static const struct attribute_group key_enumeration_group =
999 { .attrs = key_enumeration_attributes };
1002 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1003 * - show actual speed
1004 * - show/store minimum speed
1005 * - show maximum speed
1006 * - show safe speed
1007 * - show/store target speed
1008 * - show/store manual mode
1010 #define sysfs_fan_speeds_offset(offset) \
1011 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1012 applesmc_show_fan_speed, NULL, 0, offset-1); \
1014 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1015 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1017 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1018 applesmc_show_fan_speed, NULL, 2, offset-1); \
1020 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1021 applesmc_show_fan_speed, NULL, 3, offset-1); \
1023 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1024 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1026 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1027 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1029 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1030 applesmc_show_fan_position, NULL, offset-1); \
1032 static struct attribute *fan##offset##_attributes[] = { \
1033 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1034 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1035 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1036 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1037 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1038 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1039 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1040 NULL \
1044 * Create the needed functions for each fan using the macro defined above
1045 * (4 fans are supported)
1047 sysfs_fan_speeds_offset(1);
1048 sysfs_fan_speeds_offset(2);
1049 sysfs_fan_speeds_offset(3);
1050 sysfs_fan_speeds_offset(4);
1052 static const struct attribute_group fan_attribute_groups[] = {
1053 { .attrs = fan1_attributes },
1054 { .attrs = fan2_attributes },
1055 { .attrs = fan3_attributes },
1056 { .attrs = fan4_attributes },
1060 * Temperature sensors sysfs entries.
1062 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1063 applesmc_show_temperature, NULL, 0);
1064 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1065 applesmc_show_temperature, NULL, 1);
1066 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1067 applesmc_show_temperature, NULL, 2);
1068 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1069 applesmc_show_temperature, NULL, 3);
1070 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1071 applesmc_show_temperature, NULL, 4);
1072 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1073 applesmc_show_temperature, NULL, 5);
1074 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1075 applesmc_show_temperature, NULL, 6);
1076 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1077 applesmc_show_temperature, NULL, 7);
1078 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1079 applesmc_show_temperature, NULL, 8);
1080 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1081 applesmc_show_temperature, NULL, 9);
1082 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1083 applesmc_show_temperature, NULL, 10);
1084 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1085 applesmc_show_temperature, NULL, 11);
1086 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1087 applesmc_show_temperature, NULL, 12);
1088 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1089 applesmc_show_temperature, NULL, 13);
1090 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1091 applesmc_show_temperature, NULL, 14);
1092 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1093 applesmc_show_temperature, NULL, 15);
1094 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1095 applesmc_show_temperature, NULL, 16);
1096 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1097 applesmc_show_temperature, NULL, 17);
1098 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1099 applesmc_show_temperature, NULL, 18);
1100 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1101 applesmc_show_temperature, NULL, 19);
1102 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1103 applesmc_show_temperature, NULL, 20);
1104 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1105 applesmc_show_temperature, NULL, 21);
1106 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1107 applesmc_show_temperature, NULL, 22);
1108 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1109 applesmc_show_temperature, NULL, 23);
1110 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1111 applesmc_show_temperature, NULL, 24);
1112 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1113 applesmc_show_temperature, NULL, 25);
1114 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1115 applesmc_show_temperature, NULL, 26);
1116 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1117 applesmc_show_temperature, NULL, 27);
1118 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1119 applesmc_show_temperature, NULL, 28);
1120 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1121 applesmc_show_temperature, NULL, 29);
1122 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1123 applesmc_show_temperature, NULL, 30);
1124 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1125 applesmc_show_temperature, NULL, 31);
1126 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1127 applesmc_show_temperature, NULL, 32);
1128 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1129 applesmc_show_temperature, NULL, 33);
1130 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1131 applesmc_show_temperature, NULL, 34);
1133 static struct attribute *temperature_attributes[] = {
1134 &sensor_dev_attr_temp1_input.dev_attr.attr,
1135 &sensor_dev_attr_temp2_input.dev_attr.attr,
1136 &sensor_dev_attr_temp3_input.dev_attr.attr,
1137 &sensor_dev_attr_temp4_input.dev_attr.attr,
1138 &sensor_dev_attr_temp5_input.dev_attr.attr,
1139 &sensor_dev_attr_temp6_input.dev_attr.attr,
1140 &sensor_dev_attr_temp7_input.dev_attr.attr,
1141 &sensor_dev_attr_temp8_input.dev_attr.attr,
1142 &sensor_dev_attr_temp9_input.dev_attr.attr,
1143 &sensor_dev_attr_temp10_input.dev_attr.attr,
1144 &sensor_dev_attr_temp11_input.dev_attr.attr,
1145 &sensor_dev_attr_temp12_input.dev_attr.attr,
1146 &sensor_dev_attr_temp13_input.dev_attr.attr,
1147 &sensor_dev_attr_temp14_input.dev_attr.attr,
1148 &sensor_dev_attr_temp15_input.dev_attr.attr,
1149 &sensor_dev_attr_temp16_input.dev_attr.attr,
1150 &sensor_dev_attr_temp17_input.dev_attr.attr,
1151 &sensor_dev_attr_temp18_input.dev_attr.attr,
1152 &sensor_dev_attr_temp19_input.dev_attr.attr,
1153 &sensor_dev_attr_temp20_input.dev_attr.attr,
1154 &sensor_dev_attr_temp21_input.dev_attr.attr,
1155 &sensor_dev_attr_temp22_input.dev_attr.attr,
1156 &sensor_dev_attr_temp23_input.dev_attr.attr,
1157 &sensor_dev_attr_temp24_input.dev_attr.attr,
1158 &sensor_dev_attr_temp25_input.dev_attr.attr,
1159 &sensor_dev_attr_temp26_input.dev_attr.attr,
1160 &sensor_dev_attr_temp27_input.dev_attr.attr,
1161 &sensor_dev_attr_temp28_input.dev_attr.attr,
1162 &sensor_dev_attr_temp29_input.dev_attr.attr,
1163 &sensor_dev_attr_temp30_input.dev_attr.attr,
1164 &sensor_dev_attr_temp31_input.dev_attr.attr,
1165 &sensor_dev_attr_temp32_input.dev_attr.attr,
1166 &sensor_dev_attr_temp33_input.dev_attr.attr,
1167 &sensor_dev_attr_temp34_input.dev_attr.attr,
1168 &sensor_dev_attr_temp35_input.dev_attr.attr,
1169 NULL
1172 static const struct attribute_group temperature_attributes_group =
1173 { .attrs = temperature_attributes };
1175 /* Module stuff */
1178 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1180 static int applesmc_dmi_match(const struct dmi_system_id *id)
1182 int i = 0;
1183 struct dmi_match_data* dmi_data = id->driver_data;
1184 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1185 applesmc_accelerometer = dmi_data->accelerometer;
1186 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1187 applesmc_accelerometer ? "with" : "without");
1188 applesmc_light = dmi_data->light;
1189 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1190 applesmc_light ? "with" : "without");
1192 applesmc_temperature_set = dmi_data->temperature_set;
1193 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1194 i++;
1195 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1196 return 1;
1199 /* Create accelerometer ressources */
1200 static int applesmc_create_accelerometer(void)
1202 struct input_dev *idev;
1203 int ret;
1205 ret = sysfs_create_group(&pdev->dev.kobj,
1206 &accelerometer_attributes_group);
1207 if (ret)
1208 goto out;
1210 applesmc_idev = input_allocate_polled_device();
1211 if (!applesmc_idev) {
1212 ret = -ENOMEM;
1213 goto out_sysfs;
1216 applesmc_idev->poll = applesmc_idev_poll;
1217 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1219 /* initial calibrate for the input device */
1220 applesmc_calibrate();
1222 /* initialize the input device */
1223 idev = applesmc_idev->input;
1224 idev->name = "applesmc";
1225 idev->id.bustype = BUS_HOST;
1226 idev->dev.parent = &pdev->dev;
1227 idev->evbit[0] = BIT_MASK(EV_ABS);
1228 input_set_abs_params(idev, ABS_X,
1229 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1230 input_set_abs_params(idev, ABS_Y,
1231 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1233 ret = input_register_polled_device(applesmc_idev);
1234 if (ret)
1235 goto out_idev;
1237 return 0;
1239 out_idev:
1240 input_free_polled_device(applesmc_idev);
1242 out_sysfs:
1243 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1245 out:
1246 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1247 return ret;
1250 /* Release all ressources used by the accelerometer */
1251 static void applesmc_release_accelerometer(void)
1253 input_unregister_polled_device(applesmc_idev);
1254 input_free_polled_device(applesmc_idev);
1255 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1258 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1259 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1260 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1261 /* MacBook2: accelerometer and temperature set 1 */
1262 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1263 /* MacBook: accelerometer and temperature set 2 */
1264 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1265 /* MacMini: temperature set 3 */
1266 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1267 /* MacPro: temperature set 4 */
1268 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1269 /* iMac: temperature set 5 */
1270 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1271 /* MacBook3: accelerometer and temperature set 6 */
1272 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1273 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1274 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1275 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1276 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1277 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1278 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1281 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1282 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1283 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1284 { applesmc_dmi_match, "Apple MacBook Air", {
1285 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1286 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1287 &applesmc_dmi_data[7]},
1288 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1289 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1290 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1291 &applesmc_dmi_data[8]},
1292 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1293 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1294 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1295 &applesmc_dmi_data[9]},
1296 { applesmc_dmi_match, "Apple MacBook Pro", {
1297 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1298 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1299 &applesmc_dmi_data[0]},
1300 { applesmc_dmi_match, "Apple MacBook (v2)", {
1301 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1302 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1303 &applesmc_dmi_data[1]},
1304 { applesmc_dmi_match, "Apple MacBook (v3)", {
1305 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1306 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1307 &applesmc_dmi_data[6]},
1308 { applesmc_dmi_match, "Apple MacBook", {
1309 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1310 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1311 &applesmc_dmi_data[2]},
1312 { applesmc_dmi_match, "Apple Macmini", {
1313 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1314 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1315 &applesmc_dmi_data[3]},
1316 { applesmc_dmi_match, "Apple MacPro2", {
1317 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1318 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1319 &applesmc_dmi_data[4]},
1320 { applesmc_dmi_match, "Apple iMac", {
1321 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1322 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1323 &applesmc_dmi_data[5]},
1324 { .ident = NULL }
1327 static int __init applesmc_init(void)
1329 int ret;
1330 int count;
1331 int i;
1333 if (!dmi_check_system(applesmc_whitelist)) {
1334 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1335 ret = -ENODEV;
1336 goto out;
1339 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1340 "applesmc")) {
1341 ret = -ENXIO;
1342 goto out;
1345 ret = platform_driver_register(&applesmc_driver);
1346 if (ret)
1347 goto out_region;
1349 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1350 NULL, 0);
1351 if (IS_ERR(pdev)) {
1352 ret = PTR_ERR(pdev);
1353 goto out_driver;
1356 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1357 if (ret)
1358 goto out_device;
1360 /* Create key enumeration sysfs files */
1361 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1362 if (ret)
1363 goto out_name;
1365 /* create fan files */
1366 count = applesmc_get_fan_count();
1367 if (count < 0) {
1368 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1369 } else {
1370 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1372 switch (count) {
1373 default:
1374 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1375 " but at most 4 fans are supported"
1376 " by the driver.\n");
1377 case 4:
1378 ret = sysfs_create_group(&pdev->dev.kobj,
1379 &fan_attribute_groups[3]);
1380 if (ret)
1381 goto out_key_enumeration;
1382 case 3:
1383 ret = sysfs_create_group(&pdev->dev.kobj,
1384 &fan_attribute_groups[2]);
1385 if (ret)
1386 goto out_key_enumeration;
1387 case 2:
1388 ret = sysfs_create_group(&pdev->dev.kobj,
1389 &fan_attribute_groups[1]);
1390 if (ret)
1391 goto out_key_enumeration;
1392 case 1:
1393 ret = sysfs_create_group(&pdev->dev.kobj,
1394 &fan_attribute_groups[0]);
1395 if (ret)
1396 goto out_fan_1;
1397 case 0:
1402 for (i = 0;
1403 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1404 i++) {
1405 if (temperature_attributes[i] == NULL) {
1406 printk(KERN_ERR "applesmc: More temperature sensors "
1407 "in temperature_sensors_sets (at least %i)"
1408 "than available sysfs files in "
1409 "temperature_attributes (%i), please report "
1410 "this bug.\n", i, i-1);
1411 goto out_temperature;
1413 ret = sysfs_create_file(&pdev->dev.kobj,
1414 temperature_attributes[i]);
1415 if (ret)
1416 goto out_temperature;
1419 if (applesmc_accelerometer) {
1420 ret = applesmc_create_accelerometer();
1421 if (ret)
1422 goto out_temperature;
1425 if (applesmc_light) {
1426 /* Add light sensor file */
1427 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1428 if (ret)
1429 goto out_accelerometer;
1431 /* Create the workqueue */
1432 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1433 if (!applesmc_led_wq) {
1434 ret = -ENOMEM;
1435 goto out_light_sysfs;
1438 /* register as a led device */
1439 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1440 if (ret < 0)
1441 goto out_light_wq;
1444 hwmon_dev = hwmon_device_register(&pdev->dev);
1445 if (IS_ERR(hwmon_dev)) {
1446 ret = PTR_ERR(hwmon_dev);
1447 goto out_light_ledclass;
1450 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1452 return 0;
1454 out_light_ledclass:
1455 if (applesmc_light)
1456 led_classdev_unregister(&applesmc_backlight);
1457 out_light_wq:
1458 if (applesmc_light)
1459 destroy_workqueue(applesmc_led_wq);
1460 out_light_sysfs:
1461 if (applesmc_light)
1462 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1463 out_accelerometer:
1464 if (applesmc_accelerometer)
1465 applesmc_release_accelerometer();
1466 out_temperature:
1467 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1468 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1469 out_fan_1:
1470 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1471 out_key_enumeration:
1472 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1473 out_name:
1474 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1475 out_device:
1476 platform_device_unregister(pdev);
1477 out_driver:
1478 platform_driver_unregister(&applesmc_driver);
1479 out_region:
1480 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1481 out:
1482 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1483 return ret;
1486 static void __exit applesmc_exit(void)
1488 hwmon_device_unregister(hwmon_dev);
1489 if (applesmc_light) {
1490 led_classdev_unregister(&applesmc_backlight);
1491 destroy_workqueue(applesmc_led_wq);
1492 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1494 if (applesmc_accelerometer)
1495 applesmc_release_accelerometer();
1496 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1497 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1498 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1499 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1500 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1501 platform_device_unregister(pdev);
1502 platform_driver_unregister(&applesmc_driver);
1503 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1505 printk(KERN_INFO "applesmc: driver unloaded.\n");
1508 module_init(applesmc_init);
1509 module_exit(applesmc_exit);
1511 MODULE_AUTHOR("Nicolas Boichat");
1512 MODULE_DESCRIPTION("Apple SMC");
1513 MODULE_LICENSE("GPL v2");