hwmon: applesmc: restore accelerometer and keyboard backlight on resume
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / hwmon / applesmc.c
blob7ea6a8f66056827970f31f13a3a3cedd135db1fd
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 },
147 /* List of keys used to read/write fan speeds */
148 static const char* fan_speed_keys[] = {
149 FAN_ACTUAL_SPEED,
150 FAN_MIN_SPEED,
151 FAN_MAX_SPEED,
152 FAN_SAFE_SPEED,
153 FAN_TARGET_SPEED
156 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
157 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
159 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
160 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
161 #define APPLESMC_INPUT_FLAT 4
163 #define SENSOR_X 0
164 #define SENSOR_Y 1
165 #define SENSOR_Z 2
167 /* Structure to be passed to DMI_MATCH function */
168 struct dmi_match_data {
169 /* Indicates whether this computer has an accelerometer. */
170 int accelerometer;
171 /* Indicates whether this computer has light sensors and keyboard backlight. */
172 int light;
173 /* Indicates which temperature sensors set to use. */
174 int temperature_set;
177 static const int debug;
178 static struct platform_device *pdev;
179 static s16 rest_x;
180 static s16 rest_y;
181 static u8 backlight_state[2];
183 static struct device *hwmon_dev;
184 static struct input_polled_dev *applesmc_idev;
186 /* Indicates whether this computer has an accelerometer. */
187 static unsigned int applesmc_accelerometer;
189 /* Indicates whether this computer has light sensors and keyboard backlight. */
190 static unsigned int applesmc_light;
192 /* Indicates which temperature sensors set to use. */
193 static unsigned int applesmc_temperature_set;
195 static DEFINE_MUTEX(applesmc_lock);
198 * Last index written to key_at_index sysfs file, and value to use for all other
199 * key_at_index_* sysfs files.
201 static unsigned int key_at_index;
203 static struct workqueue_struct *applesmc_led_wq;
206 * __wait_status - Wait up to 32ms for the status port to get a certain value
207 * (masked with 0x0f), returning zero if the value is obtained. Callers must
208 * hold applesmc_lock.
210 static int __wait_status(u8 val)
212 int us;
214 val = val & APPLESMC_STATUS_MASK;
216 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
217 udelay(us);
218 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
219 if (debug)
220 printk(KERN_DEBUG
221 "Waited %d us for status %x\n",
222 2 * us - APPLESMC_MIN_WAIT, val);
223 return 0;
227 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
228 val, inb(APPLESMC_CMD_PORT));
230 return -EIO;
234 * special treatment of command port - on newer macbooks, it seems necessary
235 * to resend the command byte before polling the status again. Callers must
236 * hold applesmc_lock.
238 static int send_command(u8 cmd)
240 int us;
241 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
242 outb(cmd, APPLESMC_CMD_PORT);
243 udelay(us);
244 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
245 return 0;
247 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
248 cmd, inb(APPLESMC_CMD_PORT));
249 return -EIO;
253 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
254 * Returns zero on success or a negative error on failure. Callers must
255 * hold applesmc_lock.
257 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
259 int i;
261 if (len > APPLESMC_MAX_DATA_LENGTH) {
262 printk(KERN_ERR "applesmc_read_key: cannot read more than "
263 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
264 return -EINVAL;
267 if (send_command(APPLESMC_READ_CMD))
268 return -EIO;
270 for (i = 0; i < 4; i++) {
271 outb(key[i], APPLESMC_DATA_PORT);
272 if (__wait_status(0x04))
273 return -EIO;
275 if (debug)
276 printk(KERN_DEBUG "<%s", key);
278 outb(len, APPLESMC_DATA_PORT);
279 if (debug)
280 printk(KERN_DEBUG ">%x", len);
282 for (i = 0; i < len; i++) {
283 if (__wait_status(0x05))
284 return -EIO;
285 buffer[i] = inb(APPLESMC_DATA_PORT);
286 if (debug)
287 printk(KERN_DEBUG "<%x", buffer[i]);
289 if (debug)
290 printk(KERN_DEBUG "\n");
292 return 0;
296 * applesmc_write_key - writes len bytes from buffer to a given key.
297 * Returns zero on success or a negative error on failure. Callers must
298 * hold applesmc_lock.
300 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
302 int i;
304 if (len > APPLESMC_MAX_DATA_LENGTH) {
305 printk(KERN_ERR "applesmc_write_key: cannot write more than "
306 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
307 return -EINVAL;
310 if (send_command(APPLESMC_WRITE_CMD))
311 return -EIO;
313 for (i = 0; i < 4; i++) {
314 outb(key[i], APPLESMC_DATA_PORT);
315 if (__wait_status(0x04))
316 return -EIO;
319 outb(len, APPLESMC_DATA_PORT);
321 for (i = 0; i < len; i++) {
322 if (__wait_status(0x04))
323 return -EIO;
324 outb(buffer[i], APPLESMC_DATA_PORT);
327 return 0;
331 * applesmc_get_key_at_index - get key at index, and put the result in key
332 * (char[6]). Returns zero on success or a negative error on failure. Callers
333 * must hold applesmc_lock.
335 static int applesmc_get_key_at_index(int index, char* key)
337 int i;
338 u8 readkey[4];
339 readkey[0] = index >> 24;
340 readkey[1] = index >> 16;
341 readkey[2] = index >> 8;
342 readkey[3] = index;
344 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
345 return -EIO;
347 for (i = 0; i < 4; i++) {
348 outb(readkey[i], APPLESMC_DATA_PORT);
349 if (__wait_status(0x04))
350 return -EIO;
353 outb(4, APPLESMC_DATA_PORT);
355 for (i = 0; i < 4; i++) {
356 if (__wait_status(0x05))
357 return -EIO;
358 key[i] = inb(APPLESMC_DATA_PORT);
360 key[4] = 0;
362 return 0;
366 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
367 * Returns zero on success or a negative error on failure. Callers must
368 * hold applesmc_lock.
370 static int applesmc_get_key_type(char* key, char* type)
372 int i;
374 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
375 return -EIO;
377 for (i = 0; i < 4; i++) {
378 outb(key[i], APPLESMC_DATA_PORT);
379 if (__wait_status(0x04))
380 return -EIO;
383 outb(6, APPLESMC_DATA_PORT);
385 for (i = 0; i < 6; i++) {
386 if (__wait_status(0x05))
387 return -EIO;
388 type[i] = inb(APPLESMC_DATA_PORT);
390 type[5] = 0;
392 return 0;
396 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
397 * hold applesmc_lock.
399 static int applesmc_read_motion_sensor(int index, s16* value)
401 u8 buffer[2];
402 int ret;
404 switch (index) {
405 case SENSOR_X:
406 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
407 break;
408 case SENSOR_Y:
409 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
410 break;
411 case SENSOR_Z:
412 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
413 break;
414 default:
415 ret = -EINVAL;
418 *value = ((s16)buffer[0] << 8) | buffer[1];
420 return ret;
424 * applesmc_device_init - initialize the accelerometer. Returns zero on success
425 * and negative error code on failure. Can sleep.
427 static int applesmc_device_init(void)
429 int total, ret = -ENXIO;
430 u8 buffer[2];
432 if (!applesmc_accelerometer)
433 return 0;
435 mutex_lock(&applesmc_lock);
437 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
438 if (debug)
439 printk(KERN_DEBUG "applesmc try %d\n", total);
440 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
441 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
442 if (total == INIT_TIMEOUT_MSECS) {
443 printk(KERN_DEBUG "applesmc: device has"
444 " already been initialized"
445 " (0x%02x, 0x%02x).\n",
446 buffer[0], buffer[1]);
447 } else {
448 printk(KERN_DEBUG "applesmc: device"
449 " successfully initialized"
450 " (0x%02x, 0x%02x).\n",
451 buffer[0], buffer[1]);
453 ret = 0;
454 goto out;
456 buffer[0] = 0xe0;
457 buffer[1] = 0x00;
458 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
459 msleep(INIT_WAIT_MSECS);
462 printk(KERN_WARNING "applesmc: failed to init the device\n");
464 out:
465 mutex_unlock(&applesmc_lock);
466 return ret;
470 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
471 * applesmc_lock.
473 static int applesmc_get_fan_count(void)
475 int ret;
476 u8 buffer[1];
478 mutex_lock(&applesmc_lock);
480 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
482 mutex_unlock(&applesmc_lock);
483 if (ret)
484 return ret;
485 else
486 return buffer[0];
489 /* Device model stuff */
490 static int applesmc_probe(struct platform_device *dev)
492 int ret;
494 ret = applesmc_device_init();
495 if (ret)
496 return ret;
498 printk(KERN_INFO "applesmc: device successfully initialized.\n");
499 return 0;
502 /* Synchronize device with memorized backlight state */
503 static int applesmc_pm_resume(struct device *dev)
505 mutex_lock(&applesmc_lock);
506 if (applesmc_light)
507 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
508 mutex_unlock(&applesmc_lock);
509 return 0;
512 /* Reinitialize device on resume from hibernation */
513 static int applesmc_pm_restore(struct device *dev)
515 int ret = applesmc_device_init();
516 if (ret)
517 return ret;
518 return applesmc_pm_resume(dev);
521 static struct dev_pm_ops applesmc_pm_ops = {
522 .resume = applesmc_pm_resume,
523 .restore = applesmc_pm_restore,
526 static struct platform_driver applesmc_driver = {
527 .probe = applesmc_probe,
528 .driver = {
529 .name = "applesmc",
530 .owner = THIS_MODULE,
531 .pm = &applesmc_pm_ops,
536 * applesmc_calibrate - Set our "resting" values. Callers must
537 * hold applesmc_lock.
539 static void applesmc_calibrate(void)
541 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
542 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
543 rest_x = -rest_x;
546 static void applesmc_idev_poll(struct input_polled_dev *dev)
548 struct input_dev *idev = dev->input;
549 s16 x, y;
551 mutex_lock(&applesmc_lock);
553 if (applesmc_read_motion_sensor(SENSOR_X, &x))
554 goto out;
555 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
556 goto out;
558 x = -x;
559 input_report_abs(idev, ABS_X, x - rest_x);
560 input_report_abs(idev, ABS_Y, y - rest_y);
561 input_sync(idev);
563 out:
564 mutex_unlock(&applesmc_lock);
567 /* Sysfs Files */
569 static ssize_t applesmc_name_show(struct device *dev,
570 struct device_attribute *attr, char *buf)
572 return snprintf(buf, PAGE_SIZE, "applesmc\n");
575 static ssize_t applesmc_position_show(struct device *dev,
576 struct device_attribute *attr, char *buf)
578 int ret;
579 s16 x, y, z;
581 mutex_lock(&applesmc_lock);
583 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
584 if (ret)
585 goto out;
586 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
587 if (ret)
588 goto out;
589 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
590 if (ret)
591 goto out;
593 out:
594 mutex_unlock(&applesmc_lock);
595 if (ret)
596 return ret;
597 else
598 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
601 static ssize_t applesmc_light_show(struct device *dev,
602 struct device_attribute *attr, char *sysfsbuf)
604 static int data_length;
605 int ret;
606 u8 left = 0, right = 0;
607 u8 buffer[10], query[6];
609 mutex_lock(&applesmc_lock);
611 if (!data_length) {
612 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
613 if (ret)
614 goto out;
615 data_length = clamp_val(query[0], 0, 10);
616 printk(KERN_INFO "applesmc: light sensor data length set to "
617 "%d\n", data_length);
620 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
621 /* newer macbooks report a single 10-bit bigendian value */
622 if (data_length == 10) {
623 left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2;
624 goto out;
626 left = buffer[2];
627 if (ret)
628 goto out;
629 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
630 right = buffer[2];
632 out:
633 mutex_unlock(&applesmc_lock);
634 if (ret)
635 return ret;
636 else
637 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
640 /* Displays degree Celsius * 1000 */
641 static ssize_t applesmc_show_temperature(struct device *dev,
642 struct device_attribute *devattr, char *sysfsbuf)
644 int ret;
645 u8 buffer[2];
646 unsigned int temp;
647 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
648 const char* key =
649 temperature_sensors_sets[applesmc_temperature_set][attr->index];
651 mutex_lock(&applesmc_lock);
653 ret = applesmc_read_key(key, buffer, 2);
654 temp = buffer[0]*1000;
655 temp += (buffer[1] >> 6) * 250;
657 mutex_unlock(&applesmc_lock);
659 if (ret)
660 return ret;
661 else
662 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
665 static ssize_t applesmc_show_fan_speed(struct device *dev,
666 struct device_attribute *attr, char *sysfsbuf)
668 int ret;
669 unsigned int speed = 0;
670 char newkey[5];
671 u8 buffer[2];
672 struct sensor_device_attribute_2 *sensor_attr =
673 to_sensor_dev_attr_2(attr);
675 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
676 newkey[1] = '0' + sensor_attr->index;
677 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
678 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
679 newkey[4] = 0;
681 mutex_lock(&applesmc_lock);
683 ret = applesmc_read_key(newkey, buffer, 2);
684 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
686 mutex_unlock(&applesmc_lock);
687 if (ret)
688 return ret;
689 else
690 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
693 static ssize_t applesmc_store_fan_speed(struct device *dev,
694 struct device_attribute *attr,
695 const char *sysfsbuf, size_t count)
697 int ret;
698 u32 speed;
699 char newkey[5];
700 u8 buffer[2];
701 struct sensor_device_attribute_2 *sensor_attr =
702 to_sensor_dev_attr_2(attr);
704 speed = simple_strtoul(sysfsbuf, NULL, 10);
706 if (speed > 0x4000) /* Bigger than a 14-bit value */
707 return -EINVAL;
709 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
710 newkey[1] = '0' + sensor_attr->index;
711 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
712 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
713 newkey[4] = 0;
715 mutex_lock(&applesmc_lock);
717 buffer[0] = (speed >> 6) & 0xff;
718 buffer[1] = (speed << 2) & 0xff;
719 ret = applesmc_write_key(newkey, buffer, 2);
721 mutex_unlock(&applesmc_lock);
722 if (ret)
723 return ret;
724 else
725 return count;
728 static ssize_t applesmc_show_fan_manual(struct device *dev,
729 struct device_attribute *devattr, char *sysfsbuf)
731 int ret;
732 u16 manual = 0;
733 u8 buffer[2];
734 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
736 mutex_lock(&applesmc_lock);
738 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
739 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
741 mutex_unlock(&applesmc_lock);
742 if (ret)
743 return ret;
744 else
745 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
748 static ssize_t applesmc_store_fan_manual(struct device *dev,
749 struct device_attribute *devattr,
750 const char *sysfsbuf, size_t count)
752 int ret;
753 u8 buffer[2];
754 u32 input;
755 u16 val;
756 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
758 input = simple_strtoul(sysfsbuf, NULL, 10);
760 mutex_lock(&applesmc_lock);
762 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
763 val = (buffer[0] << 8 | buffer[1]);
764 if (ret)
765 goto out;
767 if (input)
768 val = val | (0x01 << attr->index);
769 else
770 val = val & ~(0x01 << attr->index);
772 buffer[0] = (val >> 8) & 0xFF;
773 buffer[1] = val & 0xFF;
775 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
777 out:
778 mutex_unlock(&applesmc_lock);
779 if (ret)
780 return ret;
781 else
782 return count;
785 static ssize_t applesmc_show_fan_position(struct device *dev,
786 struct device_attribute *attr, char *sysfsbuf)
788 int ret;
789 char newkey[5];
790 u8 buffer[17];
791 struct sensor_device_attribute_2 *sensor_attr =
792 to_sensor_dev_attr_2(attr);
794 newkey[0] = FAN_POSITION[0];
795 newkey[1] = '0' + sensor_attr->index;
796 newkey[2] = FAN_POSITION[2];
797 newkey[3] = FAN_POSITION[3];
798 newkey[4] = 0;
800 mutex_lock(&applesmc_lock);
802 ret = applesmc_read_key(newkey, buffer, 16);
803 buffer[16] = 0;
805 mutex_unlock(&applesmc_lock);
806 if (ret)
807 return ret;
808 else
809 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
812 static ssize_t applesmc_calibrate_show(struct device *dev,
813 struct device_attribute *attr, char *sysfsbuf)
815 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
818 static ssize_t applesmc_calibrate_store(struct device *dev,
819 struct device_attribute *attr, const char *sysfsbuf, size_t count)
821 mutex_lock(&applesmc_lock);
822 applesmc_calibrate();
823 mutex_unlock(&applesmc_lock);
825 return count;
828 static void applesmc_backlight_set(struct work_struct *work)
830 mutex_lock(&applesmc_lock);
831 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
832 mutex_unlock(&applesmc_lock);
834 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
836 static void applesmc_brightness_set(struct led_classdev *led_cdev,
837 enum led_brightness value)
839 int ret;
841 backlight_state[0] = value;
842 ret = queue_work(applesmc_led_wq, &backlight_work);
844 if (debug && (!ret))
845 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
848 static ssize_t applesmc_key_count_show(struct device *dev,
849 struct device_attribute *attr, char *sysfsbuf)
851 int ret;
852 u8 buffer[4];
853 u32 count;
855 mutex_lock(&applesmc_lock);
857 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
858 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
859 ((u32)buffer[2]<<8) + buffer[3];
861 mutex_unlock(&applesmc_lock);
862 if (ret)
863 return ret;
864 else
865 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
868 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
869 struct device_attribute *attr, char *sysfsbuf)
871 char key[5];
872 char info[6];
873 int ret;
875 mutex_lock(&applesmc_lock);
877 ret = applesmc_get_key_at_index(key_at_index, key);
879 if (ret || !key[0]) {
880 mutex_unlock(&applesmc_lock);
882 return -EINVAL;
885 ret = applesmc_get_key_type(key, info);
887 if (ret) {
888 mutex_unlock(&applesmc_lock);
890 return ret;
894 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
895 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
897 ret = applesmc_read_key(key, sysfsbuf, info[0]);
899 mutex_unlock(&applesmc_lock);
901 if (!ret) {
902 return info[0];
903 } else {
904 return ret;
908 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
909 struct device_attribute *attr, char *sysfsbuf)
911 char key[5];
912 char info[6];
913 int ret;
915 mutex_lock(&applesmc_lock);
917 ret = applesmc_get_key_at_index(key_at_index, key);
919 if (ret || !key[0]) {
920 mutex_unlock(&applesmc_lock);
922 return -EINVAL;
925 ret = applesmc_get_key_type(key, info);
927 mutex_unlock(&applesmc_lock);
929 if (!ret)
930 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
931 else
932 return ret;
935 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
936 struct device_attribute *attr, char *sysfsbuf)
938 char key[5];
939 char info[6];
940 int ret;
942 mutex_lock(&applesmc_lock);
944 ret = applesmc_get_key_at_index(key_at_index, key);
946 if (ret || !key[0]) {
947 mutex_unlock(&applesmc_lock);
949 return -EINVAL;
952 ret = applesmc_get_key_type(key, info);
954 mutex_unlock(&applesmc_lock);
956 if (!ret)
957 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
958 else
959 return ret;
962 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
963 struct device_attribute *attr, char *sysfsbuf)
965 char key[5];
966 int ret;
968 mutex_lock(&applesmc_lock);
970 ret = applesmc_get_key_at_index(key_at_index, key);
972 mutex_unlock(&applesmc_lock);
974 if (!ret && key[0])
975 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
976 else
977 return -EINVAL;
980 static ssize_t applesmc_key_at_index_show(struct device *dev,
981 struct device_attribute *attr, char *sysfsbuf)
983 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
986 static ssize_t applesmc_key_at_index_store(struct device *dev,
987 struct device_attribute *attr, const char *sysfsbuf, size_t count)
989 mutex_lock(&applesmc_lock);
991 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
993 mutex_unlock(&applesmc_lock);
995 return count;
998 static struct led_classdev applesmc_backlight = {
999 .name = "smc::kbd_backlight",
1000 .default_trigger = "nand-disk",
1001 .brightness_set = applesmc_brightness_set,
1004 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
1006 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
1007 static DEVICE_ATTR(calibrate, 0644,
1008 applesmc_calibrate_show, applesmc_calibrate_store);
1010 static struct attribute *accelerometer_attributes[] = {
1011 &dev_attr_position.attr,
1012 &dev_attr_calibrate.attr,
1013 NULL
1016 static const struct attribute_group accelerometer_attributes_group =
1017 { .attrs = accelerometer_attributes };
1019 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
1021 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
1022 static DEVICE_ATTR(key_at_index, 0644,
1023 applesmc_key_at_index_show, applesmc_key_at_index_store);
1024 static DEVICE_ATTR(key_at_index_name, 0444,
1025 applesmc_key_at_index_name_show, NULL);
1026 static DEVICE_ATTR(key_at_index_type, 0444,
1027 applesmc_key_at_index_type_show, NULL);
1028 static DEVICE_ATTR(key_at_index_data_length, 0444,
1029 applesmc_key_at_index_data_length_show, NULL);
1030 static DEVICE_ATTR(key_at_index_data, 0444,
1031 applesmc_key_at_index_read_show, NULL);
1033 static struct attribute *key_enumeration_attributes[] = {
1034 &dev_attr_key_count.attr,
1035 &dev_attr_key_at_index.attr,
1036 &dev_attr_key_at_index_name.attr,
1037 &dev_attr_key_at_index_type.attr,
1038 &dev_attr_key_at_index_data_length.attr,
1039 &dev_attr_key_at_index_data.attr,
1040 NULL
1043 static const struct attribute_group key_enumeration_group =
1044 { .attrs = key_enumeration_attributes };
1047 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1048 * - show actual speed
1049 * - show/store minimum speed
1050 * - show maximum speed
1051 * - show safe speed
1052 * - show/store target speed
1053 * - show/store manual mode
1055 #define sysfs_fan_speeds_offset(offset) \
1056 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1057 applesmc_show_fan_speed, NULL, 0, offset-1); \
1059 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1060 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1062 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1063 applesmc_show_fan_speed, NULL, 2, offset-1); \
1065 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1066 applesmc_show_fan_speed, NULL, 3, offset-1); \
1068 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1069 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1071 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1072 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1074 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1075 applesmc_show_fan_position, NULL, offset-1); \
1077 static struct attribute *fan##offset##_attributes[] = { \
1078 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1079 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1080 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1081 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1082 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1083 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1084 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1085 NULL \
1089 * Create the needed functions for each fan using the macro defined above
1090 * (4 fans are supported)
1092 sysfs_fan_speeds_offset(1);
1093 sysfs_fan_speeds_offset(2);
1094 sysfs_fan_speeds_offset(3);
1095 sysfs_fan_speeds_offset(4);
1097 static const struct attribute_group fan_attribute_groups[] = {
1098 { .attrs = fan1_attributes },
1099 { .attrs = fan2_attributes },
1100 { .attrs = fan3_attributes },
1101 { .attrs = fan4_attributes },
1105 * Temperature sensors sysfs entries.
1107 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1108 applesmc_show_temperature, NULL, 0);
1109 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1110 applesmc_show_temperature, NULL, 1);
1111 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1112 applesmc_show_temperature, NULL, 2);
1113 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1114 applesmc_show_temperature, NULL, 3);
1115 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1116 applesmc_show_temperature, NULL, 4);
1117 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1118 applesmc_show_temperature, NULL, 5);
1119 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1120 applesmc_show_temperature, NULL, 6);
1121 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1122 applesmc_show_temperature, NULL, 7);
1123 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1124 applesmc_show_temperature, NULL, 8);
1125 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1126 applesmc_show_temperature, NULL, 9);
1127 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1128 applesmc_show_temperature, NULL, 10);
1129 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1130 applesmc_show_temperature, NULL, 11);
1131 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1132 applesmc_show_temperature, NULL, 12);
1133 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1134 applesmc_show_temperature, NULL, 13);
1135 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1136 applesmc_show_temperature, NULL, 14);
1137 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1138 applesmc_show_temperature, NULL, 15);
1139 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1140 applesmc_show_temperature, NULL, 16);
1141 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1142 applesmc_show_temperature, NULL, 17);
1143 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1144 applesmc_show_temperature, NULL, 18);
1145 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1146 applesmc_show_temperature, NULL, 19);
1147 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1148 applesmc_show_temperature, NULL, 20);
1149 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1150 applesmc_show_temperature, NULL, 21);
1151 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1152 applesmc_show_temperature, NULL, 22);
1153 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1154 applesmc_show_temperature, NULL, 23);
1155 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1156 applesmc_show_temperature, NULL, 24);
1157 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1158 applesmc_show_temperature, NULL, 25);
1159 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1160 applesmc_show_temperature, NULL, 26);
1161 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1162 applesmc_show_temperature, NULL, 27);
1163 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1164 applesmc_show_temperature, NULL, 28);
1165 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1166 applesmc_show_temperature, NULL, 29);
1167 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1168 applesmc_show_temperature, NULL, 30);
1169 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1170 applesmc_show_temperature, NULL, 31);
1171 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1172 applesmc_show_temperature, NULL, 32);
1173 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1174 applesmc_show_temperature, NULL, 33);
1175 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1176 applesmc_show_temperature, NULL, 34);
1177 static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
1178 applesmc_show_temperature, NULL, 35);
1179 static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
1180 applesmc_show_temperature, NULL, 36);
1181 static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
1182 applesmc_show_temperature, NULL, 37);
1183 static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
1184 applesmc_show_temperature, NULL, 38);
1185 static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
1186 applesmc_show_temperature, NULL, 39);
1188 static struct attribute *temperature_attributes[] = {
1189 &sensor_dev_attr_temp1_input.dev_attr.attr,
1190 &sensor_dev_attr_temp2_input.dev_attr.attr,
1191 &sensor_dev_attr_temp3_input.dev_attr.attr,
1192 &sensor_dev_attr_temp4_input.dev_attr.attr,
1193 &sensor_dev_attr_temp5_input.dev_attr.attr,
1194 &sensor_dev_attr_temp6_input.dev_attr.attr,
1195 &sensor_dev_attr_temp7_input.dev_attr.attr,
1196 &sensor_dev_attr_temp8_input.dev_attr.attr,
1197 &sensor_dev_attr_temp9_input.dev_attr.attr,
1198 &sensor_dev_attr_temp10_input.dev_attr.attr,
1199 &sensor_dev_attr_temp11_input.dev_attr.attr,
1200 &sensor_dev_attr_temp12_input.dev_attr.attr,
1201 &sensor_dev_attr_temp13_input.dev_attr.attr,
1202 &sensor_dev_attr_temp14_input.dev_attr.attr,
1203 &sensor_dev_attr_temp15_input.dev_attr.attr,
1204 &sensor_dev_attr_temp16_input.dev_attr.attr,
1205 &sensor_dev_attr_temp17_input.dev_attr.attr,
1206 &sensor_dev_attr_temp18_input.dev_attr.attr,
1207 &sensor_dev_attr_temp19_input.dev_attr.attr,
1208 &sensor_dev_attr_temp20_input.dev_attr.attr,
1209 &sensor_dev_attr_temp21_input.dev_attr.attr,
1210 &sensor_dev_attr_temp22_input.dev_attr.attr,
1211 &sensor_dev_attr_temp23_input.dev_attr.attr,
1212 &sensor_dev_attr_temp24_input.dev_attr.attr,
1213 &sensor_dev_attr_temp25_input.dev_attr.attr,
1214 &sensor_dev_attr_temp26_input.dev_attr.attr,
1215 &sensor_dev_attr_temp27_input.dev_attr.attr,
1216 &sensor_dev_attr_temp28_input.dev_attr.attr,
1217 &sensor_dev_attr_temp29_input.dev_attr.attr,
1218 &sensor_dev_attr_temp30_input.dev_attr.attr,
1219 &sensor_dev_attr_temp31_input.dev_attr.attr,
1220 &sensor_dev_attr_temp32_input.dev_attr.attr,
1221 &sensor_dev_attr_temp33_input.dev_attr.attr,
1222 &sensor_dev_attr_temp34_input.dev_attr.attr,
1223 &sensor_dev_attr_temp35_input.dev_attr.attr,
1224 &sensor_dev_attr_temp36_input.dev_attr.attr,
1225 &sensor_dev_attr_temp37_input.dev_attr.attr,
1226 &sensor_dev_attr_temp38_input.dev_attr.attr,
1227 &sensor_dev_attr_temp39_input.dev_attr.attr,
1228 &sensor_dev_attr_temp40_input.dev_attr.attr,
1229 NULL
1232 static const struct attribute_group temperature_attributes_group =
1233 { .attrs = temperature_attributes };
1235 /* Module stuff */
1238 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1240 static int applesmc_dmi_match(const struct dmi_system_id *id)
1242 int i = 0;
1243 struct dmi_match_data* dmi_data = id->driver_data;
1244 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1245 applesmc_accelerometer = dmi_data->accelerometer;
1246 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1247 applesmc_accelerometer ? "with" : "without");
1248 applesmc_light = dmi_data->light;
1249 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1250 applesmc_light ? "with" : "without");
1252 applesmc_temperature_set = dmi_data->temperature_set;
1253 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1254 i++;
1255 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1256 return 1;
1259 /* Create accelerometer ressources */
1260 static int applesmc_create_accelerometer(void)
1262 struct input_dev *idev;
1263 int ret;
1265 ret = sysfs_create_group(&pdev->dev.kobj,
1266 &accelerometer_attributes_group);
1267 if (ret)
1268 goto out;
1270 applesmc_idev = input_allocate_polled_device();
1271 if (!applesmc_idev) {
1272 ret = -ENOMEM;
1273 goto out_sysfs;
1276 applesmc_idev->poll = applesmc_idev_poll;
1277 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1279 /* initial calibrate for the input device */
1280 applesmc_calibrate();
1282 /* initialize the input device */
1283 idev = applesmc_idev->input;
1284 idev->name = "applesmc";
1285 idev->id.bustype = BUS_HOST;
1286 idev->dev.parent = &pdev->dev;
1287 idev->evbit[0] = BIT_MASK(EV_ABS);
1288 input_set_abs_params(idev, ABS_X,
1289 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1290 input_set_abs_params(idev, ABS_Y,
1291 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1293 ret = input_register_polled_device(applesmc_idev);
1294 if (ret)
1295 goto out_idev;
1297 return 0;
1299 out_idev:
1300 input_free_polled_device(applesmc_idev);
1302 out_sysfs:
1303 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1305 out:
1306 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1307 return ret;
1310 /* Release all ressources used by the accelerometer */
1311 static void applesmc_release_accelerometer(void)
1313 input_unregister_polled_device(applesmc_idev);
1314 input_free_polled_device(applesmc_idev);
1315 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1318 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1319 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1320 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1321 /* MacBook2: accelerometer and temperature set 1 */
1322 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1323 /* MacBook: accelerometer and temperature set 2 */
1324 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1325 /* MacMini: temperature set 3 */
1326 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1327 /* MacPro: temperature set 4 */
1328 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1329 /* iMac: temperature set 5 */
1330 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1331 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1332 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1333 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1334 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1335 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1336 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1337 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1338 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1339 /* iMac 5: light sensor only, temperature set 10 */
1340 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1341 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1342 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
1343 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1344 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
1345 /* iMac 8: light sensor only, temperature set 13 */
1346 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
1347 /* iMac 6: light sensor only, temperature set 14 */
1348 { .accelerometer = 0, .light = 0, .temperature_set = 14 },
1349 /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
1350 { .accelerometer = 1, .light = 1, .temperature_set = 15 },
1351 /* MacPro3,1: temperature set 16 */
1352 { .accelerometer = 0, .light = 0, .temperature_set = 16 },
1355 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1356 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1357 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1358 { applesmc_dmi_match, "Apple MacBook Air 2", {
1359 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1360 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
1361 &applesmc_dmi_data[15]},
1362 { applesmc_dmi_match, "Apple MacBook Air", {
1363 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1364 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1365 &applesmc_dmi_data[7]},
1366 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1367 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1368 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1369 &applesmc_dmi_data[12]},
1370 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1371 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1372 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1373 &applesmc_dmi_data[8]},
1374 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1375 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1376 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1377 &applesmc_dmi_data[9]},
1378 { applesmc_dmi_match, "Apple MacBook Pro", {
1379 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1380 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1381 &applesmc_dmi_data[0]},
1382 { applesmc_dmi_match, "Apple MacBook (v2)", {
1383 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1384 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1385 &applesmc_dmi_data[1]},
1386 { applesmc_dmi_match, "Apple MacBook (v3)", {
1387 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1388 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1389 &applesmc_dmi_data[6]},
1390 { applesmc_dmi_match, "Apple MacBook 4", {
1391 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1392 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1393 &applesmc_dmi_data[6]},
1394 { applesmc_dmi_match, "Apple MacBook 5", {
1395 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1396 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1397 &applesmc_dmi_data[11]},
1398 { applesmc_dmi_match, "Apple MacBook", {
1399 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1400 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1401 &applesmc_dmi_data[2]},
1402 { applesmc_dmi_match, "Apple Macmini", {
1403 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1404 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1405 &applesmc_dmi_data[3]},
1406 { applesmc_dmi_match, "Apple MacPro2", {
1407 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1408 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1409 &applesmc_dmi_data[4]},
1410 { applesmc_dmi_match, "Apple MacPro3", {
1411 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1412 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") },
1413 &applesmc_dmi_data[16]},
1414 { applesmc_dmi_match, "Apple MacPro", {
1415 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1416 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1417 &applesmc_dmi_data[4]},
1418 { applesmc_dmi_match, "Apple iMac 8", {
1419 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1420 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1421 &applesmc_dmi_data[13]},
1422 { applesmc_dmi_match, "Apple iMac 6", {
1423 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1424 DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
1425 &applesmc_dmi_data[14]},
1426 { applesmc_dmi_match, "Apple iMac 5", {
1427 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1428 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1429 &applesmc_dmi_data[10]},
1430 { applesmc_dmi_match, "Apple iMac", {
1431 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1432 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1433 &applesmc_dmi_data[5]},
1434 { .ident = NULL }
1437 static int __init applesmc_init(void)
1439 int ret;
1440 int count;
1441 int i;
1443 if (!dmi_check_system(applesmc_whitelist)) {
1444 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1445 ret = -ENODEV;
1446 goto out;
1449 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1450 "applesmc")) {
1451 ret = -ENXIO;
1452 goto out;
1455 ret = platform_driver_register(&applesmc_driver);
1456 if (ret)
1457 goto out_region;
1459 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1460 NULL, 0);
1461 if (IS_ERR(pdev)) {
1462 ret = PTR_ERR(pdev);
1463 goto out_driver;
1466 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1467 if (ret)
1468 goto out_device;
1470 /* Create key enumeration sysfs files */
1471 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1472 if (ret)
1473 goto out_name;
1475 /* create fan files */
1476 count = applesmc_get_fan_count();
1477 if (count < 0) {
1478 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1479 } else {
1480 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1482 switch (count) {
1483 default:
1484 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1485 " but at most 4 fans are supported"
1486 " by the driver.\n");
1487 case 4:
1488 ret = sysfs_create_group(&pdev->dev.kobj,
1489 &fan_attribute_groups[3]);
1490 if (ret)
1491 goto out_key_enumeration;
1492 case 3:
1493 ret = sysfs_create_group(&pdev->dev.kobj,
1494 &fan_attribute_groups[2]);
1495 if (ret)
1496 goto out_key_enumeration;
1497 case 2:
1498 ret = sysfs_create_group(&pdev->dev.kobj,
1499 &fan_attribute_groups[1]);
1500 if (ret)
1501 goto out_key_enumeration;
1502 case 1:
1503 ret = sysfs_create_group(&pdev->dev.kobj,
1504 &fan_attribute_groups[0]);
1505 if (ret)
1506 goto out_fan_1;
1507 case 0:
1512 for (i = 0;
1513 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1514 i++) {
1515 if (temperature_attributes[i] == NULL) {
1516 printk(KERN_ERR "applesmc: More temperature sensors "
1517 "in temperature_sensors_sets (at least %i)"
1518 "than available sysfs files in "
1519 "temperature_attributes (%i), please report "
1520 "this bug.\n", i, i-1);
1521 goto out_temperature;
1523 ret = sysfs_create_file(&pdev->dev.kobj,
1524 temperature_attributes[i]);
1525 if (ret)
1526 goto out_temperature;
1529 if (applesmc_accelerometer) {
1530 ret = applesmc_create_accelerometer();
1531 if (ret)
1532 goto out_temperature;
1535 if (applesmc_light) {
1536 /* Add light sensor file */
1537 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1538 if (ret)
1539 goto out_accelerometer;
1541 /* Create the workqueue */
1542 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1543 if (!applesmc_led_wq) {
1544 ret = -ENOMEM;
1545 goto out_light_sysfs;
1548 /* register as a led device */
1549 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1550 if (ret < 0)
1551 goto out_light_wq;
1554 hwmon_dev = hwmon_device_register(&pdev->dev);
1555 if (IS_ERR(hwmon_dev)) {
1556 ret = PTR_ERR(hwmon_dev);
1557 goto out_light_ledclass;
1560 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1562 return 0;
1564 out_light_ledclass:
1565 if (applesmc_light)
1566 led_classdev_unregister(&applesmc_backlight);
1567 out_light_wq:
1568 if (applesmc_light)
1569 destroy_workqueue(applesmc_led_wq);
1570 out_light_sysfs:
1571 if (applesmc_light)
1572 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1573 out_accelerometer:
1574 if (applesmc_accelerometer)
1575 applesmc_release_accelerometer();
1576 out_temperature:
1577 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1578 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1579 out_fan_1:
1580 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1581 out_key_enumeration:
1582 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1583 out_name:
1584 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1585 out_device:
1586 platform_device_unregister(pdev);
1587 out_driver:
1588 platform_driver_unregister(&applesmc_driver);
1589 out_region:
1590 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1591 out:
1592 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1593 return ret;
1596 static void __exit applesmc_exit(void)
1598 hwmon_device_unregister(hwmon_dev);
1599 if (applesmc_light) {
1600 led_classdev_unregister(&applesmc_backlight);
1601 destroy_workqueue(applesmc_led_wq);
1602 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1604 if (applesmc_accelerometer)
1605 applesmc_release_accelerometer();
1606 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1607 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1608 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1609 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1610 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1611 platform_device_unregister(pdev);
1612 platform_driver_unregister(&applesmc_driver);
1613 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1615 printk(KERN_INFO "applesmc: driver unloaded.\n");
1618 module_init(applesmc_init);
1619 module_exit(applesmc_exit);
1621 MODULE_AUTHOR("Nicolas Boichat");
1622 MODULE_DESCRIPTION("Apple SMC");
1623 MODULE_LICENSE("GPL v2");
1624 MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);