smsc911x: Add spinlocks around registers access
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / hwmon / applesmc.c
blobf085c18d2905a602d465ef01a8d08b2a29467c28
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 <linux/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[][41] = {
87 /* Set 0: Macbook Pro */
88 { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
89 "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
90 /* Set 1: Macbook2 set */
91 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "TTF0", "Th0H",
92 "Th0S", "Th1H", NULL },
93 /* Set 2: Macbook set */
94 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S",
95 "Th1H", "Ts0P", NULL },
96 /* Set 3: Macmini set */
97 { "TC0D", "TC0P", NULL },
98 /* Set 4: Mac Pro (2 x Quad-Core) */
99 { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
100 "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P",
101 "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S",
102 "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P",
103 "TM9S", "TN0H", "TS0C", NULL },
104 /* Set 5: iMac */
105 { "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P",
106 "Tp0C", NULL },
107 /* Set 6: Macbook3 set */
108 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H",
109 "Th0S", "Th1H", NULL },
110 /* Set 7: Macbook Air */
111 { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TC0P", "TCFP",
112 "TTF0", "TW0P", "Th0H", "Tp0P", "TpFP", "Ts0P", "Ts0S", NULL },
113 /* Set 8: Macbook Pro 4,1 (Penryn) */
114 { "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", "Th0H",
115 "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
116 /* Set 9: Macbook Pro 3,1 (Santa Rosa) */
117 { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P",
118 "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
119 /* Set 10: iMac 5,1 */
120 { "TA0P", "TC0D", "TC0P", "TG0D", "TH0P", "TO0P", "Tm0P", NULL },
121 /* Set 11: Macbook 5,1 */
122 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0P", "TN0D", "TN0P",
123 "TTF0", "Th0H", "Th1H", "ThFH", "Ts0P", "Ts0S", NULL },
124 /* Set 12: Macbook Pro 5,1 */
125 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D",
126 "TG0F", "TG0H", "TG0P", "TG0T", "TG1H", "TN0D", "TN0P", "TTF0",
127 "Th2H", "Tm0P", "Ts0P", "Ts0S", NULL },
128 /* Set 13: iMac 8,1 */
129 { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P",
130 "TL0P", "TO0P", "TW0P", "Tm0P", "Tp0P", NULL },
131 /* Set 14: iMac 6,1 */
132 { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P",
133 "TO0P", "Tp0P", NULL },
134 /* Set 15: MacBook Air 2,1 */
135 { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TN0D", "TTF0",
136 "TV0P", "TVFP", "TW0P", "Th0P", "Tp0P", "Tp1P", "TpFP", "Ts0P",
137 "Ts0S", NULL },
138 /* Set 16: Mac Pro 3,1 (2 x Quad-Core) */
139 { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
140 "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "TH0P", "TH1P",
141 "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", "TM1P",
142 "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S",
143 "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S",
144 NULL },
145 /* Set 17: iMac 9,1 */
146 { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P",
147 "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL },
148 /* Set 18: MacBook Pro 2,2 */
149 { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0",
150 "Th0H", "Th1H", "Tm0P", "Ts0P", NULL },
153 /* List of keys used to read/write fan speeds */
154 static const char* fan_speed_keys[] = {
155 FAN_ACTUAL_SPEED,
156 FAN_MIN_SPEED,
157 FAN_MAX_SPEED,
158 FAN_SAFE_SPEED,
159 FAN_TARGET_SPEED
162 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
163 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
165 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
166 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
167 #define APPLESMC_INPUT_FLAT 4
169 #define SENSOR_X 0
170 #define SENSOR_Y 1
171 #define SENSOR_Z 2
173 /* Structure to be passed to DMI_MATCH function */
174 struct dmi_match_data {
175 /* Indicates whether this computer has an accelerometer. */
176 int accelerometer;
177 /* Indicates whether this computer has light sensors and keyboard backlight. */
178 int light;
179 /* Indicates which temperature sensors set to use. */
180 int temperature_set;
183 static const int debug;
184 static struct platform_device *pdev;
185 static s16 rest_x;
186 static s16 rest_y;
187 static u8 backlight_state[2];
189 static struct device *hwmon_dev;
190 static struct input_polled_dev *applesmc_idev;
192 /* Indicates whether this computer has an accelerometer. */
193 static unsigned int applesmc_accelerometer;
195 /* Indicates whether this computer has light sensors and keyboard backlight. */
196 static unsigned int applesmc_light;
198 /* The number of fans handled by the driver */
199 static unsigned int fans_handled;
201 /* Indicates which temperature sensors set to use. */
202 static unsigned int applesmc_temperature_set;
204 static DEFINE_MUTEX(applesmc_lock);
207 * Last index written to key_at_index sysfs file, and value to use for all other
208 * key_at_index_* sysfs files.
210 static unsigned int key_at_index;
212 static struct workqueue_struct *applesmc_led_wq;
215 * __wait_status - Wait up to 32ms for the status port to get a certain value
216 * (masked with 0x0f), returning zero if the value is obtained. Callers must
217 * hold applesmc_lock.
219 static int __wait_status(u8 val)
221 int us;
223 val = val & APPLESMC_STATUS_MASK;
225 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
226 udelay(us);
227 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
228 if (debug)
229 printk(KERN_DEBUG
230 "Waited %d us for status %x\n",
231 2 * us - APPLESMC_MIN_WAIT, val);
232 return 0;
236 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
237 val, inb(APPLESMC_CMD_PORT));
239 return -EIO;
243 * special treatment of command port - on newer macbooks, it seems necessary
244 * to resend the command byte before polling the status again. Callers must
245 * hold applesmc_lock.
247 static int send_command(u8 cmd)
249 int us;
250 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
251 outb(cmd, APPLESMC_CMD_PORT);
252 udelay(us);
253 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
254 return 0;
256 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
257 cmd, inb(APPLESMC_CMD_PORT));
258 return -EIO;
262 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
263 * Returns zero on success or a negative error on failure. Callers must
264 * hold applesmc_lock.
266 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
268 int i;
270 if (len > APPLESMC_MAX_DATA_LENGTH) {
271 printk(KERN_ERR "applesmc_read_key: cannot read more than "
272 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
273 return -EINVAL;
276 if (send_command(APPLESMC_READ_CMD))
277 return -EIO;
279 for (i = 0; i < 4; i++) {
280 outb(key[i], APPLESMC_DATA_PORT);
281 if (__wait_status(0x04))
282 return -EIO;
284 if (debug)
285 printk(KERN_DEBUG "<%s", key);
287 outb(len, APPLESMC_DATA_PORT);
288 if (debug)
289 printk(KERN_DEBUG ">%x", len);
291 for (i = 0; i < len; i++) {
292 if (__wait_status(0x05))
293 return -EIO;
294 buffer[i] = inb(APPLESMC_DATA_PORT);
295 if (debug)
296 printk(KERN_DEBUG "<%x", buffer[i]);
298 if (debug)
299 printk(KERN_DEBUG "\n");
301 return 0;
305 * applesmc_write_key - writes len bytes from buffer to a given key.
306 * Returns zero on success or a negative error on failure. Callers must
307 * hold applesmc_lock.
309 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
311 int i;
313 if (len > APPLESMC_MAX_DATA_LENGTH) {
314 printk(KERN_ERR "applesmc_write_key: cannot write more than "
315 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
316 return -EINVAL;
319 if (send_command(APPLESMC_WRITE_CMD))
320 return -EIO;
322 for (i = 0; i < 4; i++) {
323 outb(key[i], APPLESMC_DATA_PORT);
324 if (__wait_status(0x04))
325 return -EIO;
328 outb(len, APPLESMC_DATA_PORT);
330 for (i = 0; i < len; i++) {
331 if (__wait_status(0x04))
332 return -EIO;
333 outb(buffer[i], APPLESMC_DATA_PORT);
336 return 0;
340 * applesmc_get_key_at_index - get key at index, and put the result in key
341 * (char[6]). Returns zero on success or a negative error on failure. Callers
342 * must hold applesmc_lock.
344 static int applesmc_get_key_at_index(int index, char* key)
346 int i;
347 u8 readkey[4];
348 readkey[0] = index >> 24;
349 readkey[1] = index >> 16;
350 readkey[2] = index >> 8;
351 readkey[3] = index;
353 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
354 return -EIO;
356 for (i = 0; i < 4; i++) {
357 outb(readkey[i], APPLESMC_DATA_PORT);
358 if (__wait_status(0x04))
359 return -EIO;
362 outb(4, APPLESMC_DATA_PORT);
364 for (i = 0; i < 4; i++) {
365 if (__wait_status(0x05))
366 return -EIO;
367 key[i] = inb(APPLESMC_DATA_PORT);
369 key[4] = 0;
371 return 0;
375 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
376 * Returns zero on success or a negative error on failure. Callers must
377 * hold applesmc_lock.
379 static int applesmc_get_key_type(char* key, char* type)
381 int i;
383 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
384 return -EIO;
386 for (i = 0; i < 4; i++) {
387 outb(key[i], APPLESMC_DATA_PORT);
388 if (__wait_status(0x04))
389 return -EIO;
392 outb(6, APPLESMC_DATA_PORT);
394 for (i = 0; i < 6; i++) {
395 if (__wait_status(0x05))
396 return -EIO;
397 type[i] = inb(APPLESMC_DATA_PORT);
399 type[5] = 0;
401 return 0;
405 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
406 * hold applesmc_lock.
408 static int applesmc_read_motion_sensor(int index, s16* value)
410 u8 buffer[2];
411 int ret;
413 switch (index) {
414 case SENSOR_X:
415 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
416 break;
417 case SENSOR_Y:
418 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
419 break;
420 case SENSOR_Z:
421 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
422 break;
423 default:
424 ret = -EINVAL;
427 *value = ((s16)buffer[0] << 8) | buffer[1];
429 return ret;
433 * applesmc_device_init - initialize the accelerometer. Returns zero on success
434 * and negative error code on failure. Can sleep.
436 static int applesmc_device_init(void)
438 int total, ret = -ENXIO;
439 u8 buffer[2];
441 if (!applesmc_accelerometer)
442 return 0;
444 mutex_lock(&applesmc_lock);
446 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
447 if (debug)
448 printk(KERN_DEBUG "applesmc try %d\n", total);
449 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
450 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
451 if (total == INIT_TIMEOUT_MSECS) {
452 printk(KERN_DEBUG "applesmc: device has"
453 " already been initialized"
454 " (0x%02x, 0x%02x).\n",
455 buffer[0], buffer[1]);
456 } else {
457 printk(KERN_DEBUG "applesmc: device"
458 " successfully initialized"
459 " (0x%02x, 0x%02x).\n",
460 buffer[0], buffer[1]);
462 ret = 0;
463 goto out;
465 buffer[0] = 0xe0;
466 buffer[1] = 0x00;
467 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
468 msleep(INIT_WAIT_MSECS);
471 printk(KERN_WARNING "applesmc: failed to init the device\n");
473 out:
474 mutex_unlock(&applesmc_lock);
475 return ret;
479 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
480 * applesmc_lock.
482 static int applesmc_get_fan_count(void)
484 int ret;
485 u8 buffer[1];
487 mutex_lock(&applesmc_lock);
489 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
491 mutex_unlock(&applesmc_lock);
492 if (ret)
493 return ret;
494 else
495 return buffer[0];
498 /* Device model stuff */
499 static int applesmc_probe(struct platform_device *dev)
501 int ret;
503 ret = applesmc_device_init();
504 if (ret)
505 return ret;
507 printk(KERN_INFO "applesmc: device successfully initialized.\n");
508 return 0;
511 /* Synchronize device with memorized backlight state */
512 static int applesmc_pm_resume(struct device *dev)
514 mutex_lock(&applesmc_lock);
515 if (applesmc_light)
516 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
517 mutex_unlock(&applesmc_lock);
518 return 0;
521 /* Reinitialize device on resume from hibernation */
522 static int applesmc_pm_restore(struct device *dev)
524 int ret = applesmc_device_init();
525 if (ret)
526 return ret;
527 return applesmc_pm_resume(dev);
530 static const struct dev_pm_ops applesmc_pm_ops = {
531 .resume = applesmc_pm_resume,
532 .restore = applesmc_pm_restore,
535 static struct platform_driver applesmc_driver = {
536 .probe = applesmc_probe,
537 .driver = {
538 .name = "applesmc",
539 .owner = THIS_MODULE,
540 .pm = &applesmc_pm_ops,
545 * applesmc_calibrate - Set our "resting" values. Callers must
546 * hold applesmc_lock.
548 static void applesmc_calibrate(void)
550 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
551 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
552 rest_x = -rest_x;
555 static void applesmc_idev_poll(struct input_polled_dev *dev)
557 struct input_dev *idev = dev->input;
558 s16 x, y;
560 mutex_lock(&applesmc_lock);
562 if (applesmc_read_motion_sensor(SENSOR_X, &x))
563 goto out;
564 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
565 goto out;
567 x = -x;
568 input_report_abs(idev, ABS_X, x - rest_x);
569 input_report_abs(idev, ABS_Y, y - rest_y);
570 input_sync(idev);
572 out:
573 mutex_unlock(&applesmc_lock);
576 /* Sysfs Files */
578 static ssize_t applesmc_name_show(struct device *dev,
579 struct device_attribute *attr, char *buf)
581 return snprintf(buf, PAGE_SIZE, "applesmc\n");
584 static ssize_t applesmc_position_show(struct device *dev,
585 struct device_attribute *attr, char *buf)
587 int ret;
588 s16 x, y, z;
590 mutex_lock(&applesmc_lock);
592 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
593 if (ret)
594 goto out;
595 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
596 if (ret)
597 goto out;
598 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
599 if (ret)
600 goto out;
602 out:
603 mutex_unlock(&applesmc_lock);
604 if (ret)
605 return ret;
606 else
607 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
610 static ssize_t applesmc_light_show(struct device *dev,
611 struct device_attribute *attr, char *sysfsbuf)
613 static int data_length;
614 int ret;
615 u8 left = 0, right = 0;
616 u8 buffer[10], query[6];
618 mutex_lock(&applesmc_lock);
620 if (!data_length) {
621 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
622 if (ret)
623 goto out;
624 data_length = clamp_val(query[0], 0, 10);
625 printk(KERN_INFO "applesmc: light sensor data length set to "
626 "%d\n", data_length);
629 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
630 /* newer macbooks report a single 10-bit bigendian value */
631 if (data_length == 10) {
632 left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2;
633 goto out;
635 left = buffer[2];
636 if (ret)
637 goto out;
638 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
639 right = buffer[2];
641 out:
642 mutex_unlock(&applesmc_lock);
643 if (ret)
644 return ret;
645 else
646 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
649 /* Displays degree Celsius * 1000 */
650 static ssize_t applesmc_show_temperature(struct device *dev,
651 struct device_attribute *devattr, char *sysfsbuf)
653 int ret;
654 u8 buffer[2];
655 unsigned int temp;
656 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
657 const char* key =
658 temperature_sensors_sets[applesmc_temperature_set][attr->index];
660 mutex_lock(&applesmc_lock);
662 ret = applesmc_read_key(key, buffer, 2);
663 temp = buffer[0]*1000;
664 temp += (buffer[1] >> 6) * 250;
666 mutex_unlock(&applesmc_lock);
668 if (ret)
669 return ret;
670 else
671 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
674 static ssize_t applesmc_show_fan_speed(struct device *dev,
675 struct device_attribute *attr, char *sysfsbuf)
677 int ret;
678 unsigned int speed = 0;
679 char newkey[5];
680 u8 buffer[2];
681 struct sensor_device_attribute_2 *sensor_attr =
682 to_sensor_dev_attr_2(attr);
684 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
685 newkey[1] = '0' + sensor_attr->index;
686 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
687 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
688 newkey[4] = 0;
690 mutex_lock(&applesmc_lock);
692 ret = applesmc_read_key(newkey, buffer, 2);
693 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
695 mutex_unlock(&applesmc_lock);
696 if (ret)
697 return ret;
698 else
699 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
702 static ssize_t applesmc_store_fan_speed(struct device *dev,
703 struct device_attribute *attr,
704 const char *sysfsbuf, size_t count)
706 int ret;
707 u32 speed;
708 char newkey[5];
709 u8 buffer[2];
710 struct sensor_device_attribute_2 *sensor_attr =
711 to_sensor_dev_attr_2(attr);
713 speed = simple_strtoul(sysfsbuf, NULL, 10);
715 if (speed > 0x4000) /* Bigger than a 14-bit value */
716 return -EINVAL;
718 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
719 newkey[1] = '0' + sensor_attr->index;
720 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
721 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
722 newkey[4] = 0;
724 mutex_lock(&applesmc_lock);
726 buffer[0] = (speed >> 6) & 0xff;
727 buffer[1] = (speed << 2) & 0xff;
728 ret = applesmc_write_key(newkey, buffer, 2);
730 mutex_unlock(&applesmc_lock);
731 if (ret)
732 return ret;
733 else
734 return count;
737 static ssize_t applesmc_show_fan_manual(struct device *dev,
738 struct device_attribute *devattr, char *sysfsbuf)
740 int ret;
741 u16 manual = 0;
742 u8 buffer[2];
743 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
745 mutex_lock(&applesmc_lock);
747 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
748 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
750 mutex_unlock(&applesmc_lock);
751 if (ret)
752 return ret;
753 else
754 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
757 static ssize_t applesmc_store_fan_manual(struct device *dev,
758 struct device_attribute *devattr,
759 const char *sysfsbuf, size_t count)
761 int ret;
762 u8 buffer[2];
763 u32 input;
764 u16 val;
765 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
767 input = simple_strtoul(sysfsbuf, NULL, 10);
769 mutex_lock(&applesmc_lock);
771 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
772 val = (buffer[0] << 8 | buffer[1]);
773 if (ret)
774 goto out;
776 if (input)
777 val = val | (0x01 << attr->index);
778 else
779 val = val & ~(0x01 << attr->index);
781 buffer[0] = (val >> 8) & 0xFF;
782 buffer[1] = val & 0xFF;
784 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
786 out:
787 mutex_unlock(&applesmc_lock);
788 if (ret)
789 return ret;
790 else
791 return count;
794 static ssize_t applesmc_show_fan_position(struct device *dev,
795 struct device_attribute *attr, char *sysfsbuf)
797 int ret;
798 char newkey[5];
799 u8 buffer[17];
800 struct sensor_device_attribute_2 *sensor_attr =
801 to_sensor_dev_attr_2(attr);
803 newkey[0] = FAN_POSITION[0];
804 newkey[1] = '0' + sensor_attr->index;
805 newkey[2] = FAN_POSITION[2];
806 newkey[3] = FAN_POSITION[3];
807 newkey[4] = 0;
809 mutex_lock(&applesmc_lock);
811 ret = applesmc_read_key(newkey, buffer, 16);
812 buffer[16] = 0;
814 mutex_unlock(&applesmc_lock);
815 if (ret)
816 return ret;
817 else
818 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
821 static ssize_t applesmc_calibrate_show(struct device *dev,
822 struct device_attribute *attr, char *sysfsbuf)
824 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
827 static ssize_t applesmc_calibrate_store(struct device *dev,
828 struct device_attribute *attr, const char *sysfsbuf, size_t count)
830 mutex_lock(&applesmc_lock);
831 applesmc_calibrate();
832 mutex_unlock(&applesmc_lock);
834 return count;
837 static void applesmc_backlight_set(struct work_struct *work)
839 mutex_lock(&applesmc_lock);
840 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
841 mutex_unlock(&applesmc_lock);
843 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
845 static void applesmc_brightness_set(struct led_classdev *led_cdev,
846 enum led_brightness value)
848 int ret;
850 backlight_state[0] = value;
851 ret = queue_work(applesmc_led_wq, &backlight_work);
853 if (debug && (!ret))
854 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
857 static ssize_t applesmc_key_count_show(struct device *dev,
858 struct device_attribute *attr, char *sysfsbuf)
860 int ret;
861 u8 buffer[4];
862 u32 count;
864 mutex_lock(&applesmc_lock);
866 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
867 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
868 ((u32)buffer[2]<<8) + buffer[3];
870 mutex_unlock(&applesmc_lock);
871 if (ret)
872 return ret;
873 else
874 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
877 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
878 struct device_attribute *attr, char *sysfsbuf)
880 char key[5];
881 char info[6];
882 int ret;
884 mutex_lock(&applesmc_lock);
886 ret = applesmc_get_key_at_index(key_at_index, key);
888 if (ret || !key[0]) {
889 mutex_unlock(&applesmc_lock);
891 return -EINVAL;
894 ret = applesmc_get_key_type(key, info);
896 if (ret) {
897 mutex_unlock(&applesmc_lock);
899 return ret;
903 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
904 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
906 ret = applesmc_read_key(key, sysfsbuf, info[0]);
908 mutex_unlock(&applesmc_lock);
910 if (!ret) {
911 return info[0];
912 } else {
913 return ret;
917 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
918 struct device_attribute *attr, char *sysfsbuf)
920 char key[5];
921 char info[6];
922 int ret;
924 mutex_lock(&applesmc_lock);
926 ret = applesmc_get_key_at_index(key_at_index, key);
928 if (ret || !key[0]) {
929 mutex_unlock(&applesmc_lock);
931 return -EINVAL;
934 ret = applesmc_get_key_type(key, info);
936 mutex_unlock(&applesmc_lock);
938 if (!ret)
939 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
940 else
941 return ret;
944 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
945 struct device_attribute *attr, char *sysfsbuf)
947 char key[5];
948 char info[6];
949 int ret;
951 mutex_lock(&applesmc_lock);
953 ret = applesmc_get_key_at_index(key_at_index, key);
955 if (ret || !key[0]) {
956 mutex_unlock(&applesmc_lock);
958 return -EINVAL;
961 ret = applesmc_get_key_type(key, info);
963 mutex_unlock(&applesmc_lock);
965 if (!ret)
966 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
967 else
968 return ret;
971 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
972 struct device_attribute *attr, char *sysfsbuf)
974 char key[5];
975 int ret;
977 mutex_lock(&applesmc_lock);
979 ret = applesmc_get_key_at_index(key_at_index, key);
981 mutex_unlock(&applesmc_lock);
983 if (!ret && key[0])
984 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
985 else
986 return -EINVAL;
989 static ssize_t applesmc_key_at_index_show(struct device *dev,
990 struct device_attribute *attr, char *sysfsbuf)
992 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
995 static ssize_t applesmc_key_at_index_store(struct device *dev,
996 struct device_attribute *attr, const char *sysfsbuf, size_t count)
998 mutex_lock(&applesmc_lock);
1000 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
1002 mutex_unlock(&applesmc_lock);
1004 return count;
1007 static struct led_classdev applesmc_backlight = {
1008 .name = "smc::kbd_backlight",
1009 .default_trigger = "nand-disk",
1010 .brightness_set = applesmc_brightness_set,
1013 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
1015 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
1016 static DEVICE_ATTR(calibrate, 0644,
1017 applesmc_calibrate_show, applesmc_calibrate_store);
1019 static struct attribute *accelerometer_attributes[] = {
1020 &dev_attr_position.attr,
1021 &dev_attr_calibrate.attr,
1022 NULL
1025 static const struct attribute_group accelerometer_attributes_group =
1026 { .attrs = accelerometer_attributes };
1028 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
1030 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
1031 static DEVICE_ATTR(key_at_index, 0644,
1032 applesmc_key_at_index_show, applesmc_key_at_index_store);
1033 static DEVICE_ATTR(key_at_index_name, 0444,
1034 applesmc_key_at_index_name_show, NULL);
1035 static DEVICE_ATTR(key_at_index_type, 0444,
1036 applesmc_key_at_index_type_show, NULL);
1037 static DEVICE_ATTR(key_at_index_data_length, 0444,
1038 applesmc_key_at_index_data_length_show, NULL);
1039 static DEVICE_ATTR(key_at_index_data, 0444,
1040 applesmc_key_at_index_read_show, NULL);
1042 static struct attribute *key_enumeration_attributes[] = {
1043 &dev_attr_key_count.attr,
1044 &dev_attr_key_at_index.attr,
1045 &dev_attr_key_at_index_name.attr,
1046 &dev_attr_key_at_index_type.attr,
1047 &dev_attr_key_at_index_data_length.attr,
1048 &dev_attr_key_at_index_data.attr,
1049 NULL
1052 static const struct attribute_group key_enumeration_group =
1053 { .attrs = key_enumeration_attributes };
1056 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1057 * - show actual speed
1058 * - show/store minimum speed
1059 * - show maximum speed
1060 * - show safe speed
1061 * - show/store target speed
1062 * - show/store manual mode
1064 #define sysfs_fan_speeds_offset(offset) \
1065 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1066 applesmc_show_fan_speed, NULL, 0, offset-1); \
1068 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1069 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1071 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1072 applesmc_show_fan_speed, NULL, 2, offset-1); \
1074 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1075 applesmc_show_fan_speed, NULL, 3, offset-1); \
1077 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1078 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1080 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1081 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1083 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1084 applesmc_show_fan_position, NULL, offset-1); \
1086 static struct attribute *fan##offset##_attributes[] = { \
1087 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1088 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1089 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1090 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1091 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1092 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1093 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1094 NULL \
1098 * Create the needed functions for each fan using the macro defined above
1099 * (4 fans are supported)
1101 sysfs_fan_speeds_offset(1);
1102 sysfs_fan_speeds_offset(2);
1103 sysfs_fan_speeds_offset(3);
1104 sysfs_fan_speeds_offset(4);
1106 static const struct attribute_group fan_attribute_groups[] = {
1107 { .attrs = fan1_attributes },
1108 { .attrs = fan2_attributes },
1109 { .attrs = fan3_attributes },
1110 { .attrs = fan4_attributes },
1114 * Temperature sensors sysfs entries.
1116 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1117 applesmc_show_temperature, NULL, 0);
1118 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1119 applesmc_show_temperature, NULL, 1);
1120 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1121 applesmc_show_temperature, NULL, 2);
1122 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1123 applesmc_show_temperature, NULL, 3);
1124 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1125 applesmc_show_temperature, NULL, 4);
1126 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1127 applesmc_show_temperature, NULL, 5);
1128 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1129 applesmc_show_temperature, NULL, 6);
1130 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1131 applesmc_show_temperature, NULL, 7);
1132 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1133 applesmc_show_temperature, NULL, 8);
1134 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1135 applesmc_show_temperature, NULL, 9);
1136 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1137 applesmc_show_temperature, NULL, 10);
1138 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1139 applesmc_show_temperature, NULL, 11);
1140 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1141 applesmc_show_temperature, NULL, 12);
1142 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1143 applesmc_show_temperature, NULL, 13);
1144 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1145 applesmc_show_temperature, NULL, 14);
1146 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1147 applesmc_show_temperature, NULL, 15);
1148 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1149 applesmc_show_temperature, NULL, 16);
1150 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1151 applesmc_show_temperature, NULL, 17);
1152 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1153 applesmc_show_temperature, NULL, 18);
1154 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1155 applesmc_show_temperature, NULL, 19);
1156 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1157 applesmc_show_temperature, NULL, 20);
1158 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1159 applesmc_show_temperature, NULL, 21);
1160 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1161 applesmc_show_temperature, NULL, 22);
1162 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1163 applesmc_show_temperature, NULL, 23);
1164 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1165 applesmc_show_temperature, NULL, 24);
1166 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1167 applesmc_show_temperature, NULL, 25);
1168 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1169 applesmc_show_temperature, NULL, 26);
1170 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1171 applesmc_show_temperature, NULL, 27);
1172 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1173 applesmc_show_temperature, NULL, 28);
1174 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1175 applesmc_show_temperature, NULL, 29);
1176 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1177 applesmc_show_temperature, NULL, 30);
1178 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1179 applesmc_show_temperature, NULL, 31);
1180 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1181 applesmc_show_temperature, NULL, 32);
1182 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1183 applesmc_show_temperature, NULL, 33);
1184 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1185 applesmc_show_temperature, NULL, 34);
1186 static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
1187 applesmc_show_temperature, NULL, 35);
1188 static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
1189 applesmc_show_temperature, NULL, 36);
1190 static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
1191 applesmc_show_temperature, NULL, 37);
1192 static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
1193 applesmc_show_temperature, NULL, 38);
1194 static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
1195 applesmc_show_temperature, NULL, 39);
1197 static struct attribute *temperature_attributes[] = {
1198 &sensor_dev_attr_temp1_input.dev_attr.attr,
1199 &sensor_dev_attr_temp2_input.dev_attr.attr,
1200 &sensor_dev_attr_temp3_input.dev_attr.attr,
1201 &sensor_dev_attr_temp4_input.dev_attr.attr,
1202 &sensor_dev_attr_temp5_input.dev_attr.attr,
1203 &sensor_dev_attr_temp6_input.dev_attr.attr,
1204 &sensor_dev_attr_temp7_input.dev_attr.attr,
1205 &sensor_dev_attr_temp8_input.dev_attr.attr,
1206 &sensor_dev_attr_temp9_input.dev_attr.attr,
1207 &sensor_dev_attr_temp10_input.dev_attr.attr,
1208 &sensor_dev_attr_temp11_input.dev_attr.attr,
1209 &sensor_dev_attr_temp12_input.dev_attr.attr,
1210 &sensor_dev_attr_temp13_input.dev_attr.attr,
1211 &sensor_dev_attr_temp14_input.dev_attr.attr,
1212 &sensor_dev_attr_temp15_input.dev_attr.attr,
1213 &sensor_dev_attr_temp16_input.dev_attr.attr,
1214 &sensor_dev_attr_temp17_input.dev_attr.attr,
1215 &sensor_dev_attr_temp18_input.dev_attr.attr,
1216 &sensor_dev_attr_temp19_input.dev_attr.attr,
1217 &sensor_dev_attr_temp20_input.dev_attr.attr,
1218 &sensor_dev_attr_temp21_input.dev_attr.attr,
1219 &sensor_dev_attr_temp22_input.dev_attr.attr,
1220 &sensor_dev_attr_temp23_input.dev_attr.attr,
1221 &sensor_dev_attr_temp24_input.dev_attr.attr,
1222 &sensor_dev_attr_temp25_input.dev_attr.attr,
1223 &sensor_dev_attr_temp26_input.dev_attr.attr,
1224 &sensor_dev_attr_temp27_input.dev_attr.attr,
1225 &sensor_dev_attr_temp28_input.dev_attr.attr,
1226 &sensor_dev_attr_temp29_input.dev_attr.attr,
1227 &sensor_dev_attr_temp30_input.dev_attr.attr,
1228 &sensor_dev_attr_temp31_input.dev_attr.attr,
1229 &sensor_dev_attr_temp32_input.dev_attr.attr,
1230 &sensor_dev_attr_temp33_input.dev_attr.attr,
1231 &sensor_dev_attr_temp34_input.dev_attr.attr,
1232 &sensor_dev_attr_temp35_input.dev_attr.attr,
1233 &sensor_dev_attr_temp36_input.dev_attr.attr,
1234 &sensor_dev_attr_temp37_input.dev_attr.attr,
1235 &sensor_dev_attr_temp38_input.dev_attr.attr,
1236 &sensor_dev_attr_temp39_input.dev_attr.attr,
1237 &sensor_dev_attr_temp40_input.dev_attr.attr,
1238 NULL
1241 static const struct attribute_group temperature_attributes_group =
1242 { .attrs = temperature_attributes };
1244 /* Module stuff */
1247 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1249 static int applesmc_dmi_match(const struct dmi_system_id *id)
1251 int i = 0;
1252 struct dmi_match_data* dmi_data = id->driver_data;
1253 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1254 applesmc_accelerometer = dmi_data->accelerometer;
1255 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1256 applesmc_accelerometer ? "with" : "without");
1257 applesmc_light = dmi_data->light;
1258 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1259 applesmc_light ? "with" : "without");
1261 applesmc_temperature_set = dmi_data->temperature_set;
1262 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1263 i++;
1264 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1265 return 1;
1268 /* Create accelerometer ressources */
1269 static int applesmc_create_accelerometer(void)
1271 struct input_dev *idev;
1272 int ret;
1274 ret = sysfs_create_group(&pdev->dev.kobj,
1275 &accelerometer_attributes_group);
1276 if (ret)
1277 goto out;
1279 applesmc_idev = input_allocate_polled_device();
1280 if (!applesmc_idev) {
1281 ret = -ENOMEM;
1282 goto out_sysfs;
1285 applesmc_idev->poll = applesmc_idev_poll;
1286 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1288 /* initial calibrate for the input device */
1289 applesmc_calibrate();
1291 /* initialize the input device */
1292 idev = applesmc_idev->input;
1293 idev->name = "applesmc";
1294 idev->id.bustype = BUS_HOST;
1295 idev->dev.parent = &pdev->dev;
1296 idev->evbit[0] = BIT_MASK(EV_ABS);
1297 input_set_abs_params(idev, ABS_X,
1298 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1299 input_set_abs_params(idev, ABS_Y,
1300 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1302 ret = input_register_polled_device(applesmc_idev);
1303 if (ret)
1304 goto out_idev;
1306 return 0;
1308 out_idev:
1309 input_free_polled_device(applesmc_idev);
1311 out_sysfs:
1312 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1314 out:
1315 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1316 return ret;
1319 /* Release all ressources used by the accelerometer */
1320 static void applesmc_release_accelerometer(void)
1322 input_unregister_polled_device(applesmc_idev);
1323 input_free_polled_device(applesmc_idev);
1324 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1327 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1328 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1329 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1330 /* MacBook2: accelerometer and temperature set 1 */
1331 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1332 /* MacBook: accelerometer and temperature set 2 */
1333 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1334 /* MacMini: temperature set 3 */
1335 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1336 /* MacPro: temperature set 4 */
1337 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1338 /* iMac: temperature set 5 */
1339 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1340 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1341 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1342 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1343 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1344 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1345 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1346 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1347 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1348 /* iMac 5: light sensor only, temperature set 10 */
1349 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1350 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1351 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
1352 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1353 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
1354 /* iMac 8: light sensor only, temperature set 13 */
1355 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
1356 /* iMac 6: light sensor only, temperature set 14 */
1357 { .accelerometer = 0, .light = 0, .temperature_set = 14 },
1358 /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
1359 { .accelerometer = 1, .light = 1, .temperature_set = 15 },
1360 /* MacPro3,1: temperature set 16 */
1361 { .accelerometer = 0, .light = 0, .temperature_set = 16 },
1362 /* iMac 9,1: light sensor only, temperature set 17 */
1363 { .accelerometer = 0, .light = 0, .temperature_set = 17 },
1364 /* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
1365 { .accelerometer = 1, .light = 1, .temperature_set = 18 },
1368 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1369 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1370 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1371 { applesmc_dmi_match, "Apple MacBook Air 2", {
1372 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1373 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
1374 &applesmc_dmi_data[15]},
1375 { applesmc_dmi_match, "Apple MacBook Air", {
1376 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1377 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1378 &applesmc_dmi_data[7]},
1379 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1380 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1381 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1382 &applesmc_dmi_data[12]},
1383 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1384 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1385 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1386 &applesmc_dmi_data[8]},
1387 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1388 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1389 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1390 &applesmc_dmi_data[9]},
1391 { applesmc_dmi_match, "Apple MacBook Pro 2,2", {
1392 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
1393 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
1394 &applesmc_dmi_data[18]},
1395 { applesmc_dmi_match, "Apple MacBook Pro", {
1396 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1397 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1398 &applesmc_dmi_data[0]},
1399 { applesmc_dmi_match, "Apple MacBook (v2)", {
1400 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1401 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1402 &applesmc_dmi_data[1]},
1403 { applesmc_dmi_match, "Apple MacBook (v3)", {
1404 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1405 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1406 &applesmc_dmi_data[6]},
1407 { applesmc_dmi_match, "Apple MacBook 4", {
1408 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1409 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1410 &applesmc_dmi_data[6]},
1411 { applesmc_dmi_match, "Apple MacBook 5", {
1412 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1413 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1414 &applesmc_dmi_data[11]},
1415 { applesmc_dmi_match, "Apple MacBook", {
1416 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1417 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1418 &applesmc_dmi_data[2]},
1419 { applesmc_dmi_match, "Apple Macmini", {
1420 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1421 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1422 &applesmc_dmi_data[3]},
1423 { applesmc_dmi_match, "Apple MacPro2", {
1424 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1425 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1426 &applesmc_dmi_data[4]},
1427 { applesmc_dmi_match, "Apple MacPro3", {
1428 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1429 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") },
1430 &applesmc_dmi_data[16]},
1431 { applesmc_dmi_match, "Apple MacPro", {
1432 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1433 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1434 &applesmc_dmi_data[4]},
1435 { applesmc_dmi_match, "Apple iMac 9,1", {
1436 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
1437 DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
1438 &applesmc_dmi_data[17]},
1439 { applesmc_dmi_match, "Apple iMac 8", {
1440 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1441 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1442 &applesmc_dmi_data[13]},
1443 { applesmc_dmi_match, "Apple iMac 6", {
1444 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1445 DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
1446 &applesmc_dmi_data[14]},
1447 { applesmc_dmi_match, "Apple iMac 5", {
1448 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1449 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1450 &applesmc_dmi_data[10]},
1451 { applesmc_dmi_match, "Apple iMac", {
1452 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1453 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1454 &applesmc_dmi_data[5]},
1455 { .ident = NULL }
1458 static int __init applesmc_init(void)
1460 int ret;
1461 int count;
1462 int i;
1464 if (!dmi_check_system(applesmc_whitelist)) {
1465 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1466 ret = -ENODEV;
1467 goto out;
1470 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1471 "applesmc")) {
1472 ret = -ENXIO;
1473 goto out;
1476 ret = platform_driver_register(&applesmc_driver);
1477 if (ret)
1478 goto out_region;
1480 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1481 NULL, 0);
1482 if (IS_ERR(pdev)) {
1483 ret = PTR_ERR(pdev);
1484 goto out_driver;
1487 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1488 if (ret)
1489 goto out_device;
1491 /* Create key enumeration sysfs files */
1492 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1493 if (ret)
1494 goto out_name;
1496 /* create fan files */
1497 count = applesmc_get_fan_count();
1498 if (count < 0)
1499 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1500 else
1501 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1503 if (count > 4) {
1504 count = 4;
1505 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1506 " but at most 4 fans are supported"
1507 " by the driver.\n");
1510 while (fans_handled < count) {
1511 ret = sysfs_create_group(&pdev->dev.kobj,
1512 &fan_attribute_groups[fans_handled]);
1513 if (ret)
1514 goto out_fans;
1515 fans_handled++;
1518 for (i = 0;
1519 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1520 i++) {
1521 if (temperature_attributes[i] == NULL) {
1522 printk(KERN_ERR "applesmc: More temperature sensors "
1523 "in temperature_sensors_sets (at least %i)"
1524 "than available sysfs files in "
1525 "temperature_attributes (%i), please report "
1526 "this bug.\n", i, i-1);
1527 goto out_temperature;
1529 ret = sysfs_create_file(&pdev->dev.kobj,
1530 temperature_attributes[i]);
1531 if (ret)
1532 goto out_temperature;
1535 if (applesmc_accelerometer) {
1536 ret = applesmc_create_accelerometer();
1537 if (ret)
1538 goto out_temperature;
1541 if (applesmc_light) {
1542 /* Add light sensor file */
1543 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1544 if (ret)
1545 goto out_accelerometer;
1547 /* Create the workqueue */
1548 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1549 if (!applesmc_led_wq) {
1550 ret = -ENOMEM;
1551 goto out_light_sysfs;
1554 /* register as a led device */
1555 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1556 if (ret < 0)
1557 goto out_light_wq;
1560 hwmon_dev = hwmon_device_register(&pdev->dev);
1561 if (IS_ERR(hwmon_dev)) {
1562 ret = PTR_ERR(hwmon_dev);
1563 goto out_light_ledclass;
1566 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1568 return 0;
1570 out_light_ledclass:
1571 if (applesmc_light)
1572 led_classdev_unregister(&applesmc_backlight);
1573 out_light_wq:
1574 if (applesmc_light)
1575 destroy_workqueue(applesmc_led_wq);
1576 out_light_sysfs:
1577 if (applesmc_light)
1578 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1579 out_accelerometer:
1580 if (applesmc_accelerometer)
1581 applesmc_release_accelerometer();
1582 out_temperature:
1583 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1584 out_fans:
1585 while (fans_handled)
1586 sysfs_remove_group(&pdev->dev.kobj,
1587 &fan_attribute_groups[--fans_handled]);
1588 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1589 out_name:
1590 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1591 out_device:
1592 platform_device_unregister(pdev);
1593 out_driver:
1594 platform_driver_unregister(&applesmc_driver);
1595 out_region:
1596 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1597 out:
1598 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1599 return ret;
1602 static void __exit applesmc_exit(void)
1604 hwmon_device_unregister(hwmon_dev);
1605 if (applesmc_light) {
1606 led_classdev_unregister(&applesmc_backlight);
1607 destroy_workqueue(applesmc_led_wq);
1608 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1610 if (applesmc_accelerometer)
1611 applesmc_release_accelerometer();
1612 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1613 while (fans_handled)
1614 sysfs_remove_group(&pdev->dev.kobj,
1615 &fan_attribute_groups[--fans_handled]);
1616 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1617 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1618 platform_device_unregister(pdev);
1619 platform_driver_unregister(&applesmc_driver);
1620 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1622 printk(KERN_INFO "applesmc: driver unloaded.\n");
1625 module_init(applesmc_init);
1626 module_exit(applesmc_exit);
1628 MODULE_AUTHOR("Nicolas Boichat");
1629 MODULE_DESCRIPTION("Apple SMC");
1630 MODULE_LICENSE("GPL v2");
1631 MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);