Staging: strip: delete the driver
[linux/fpc-iii.git] / drivers / hwmon / applesmc.c
blob0f28d91f29d8ef81c50b036bad0c84ca78e76bd8
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 /* Indicates which temperature sensors set to use. */
199 static unsigned int applesmc_temperature_set;
201 static DEFINE_MUTEX(applesmc_lock);
204 * Last index written to key_at_index sysfs file, and value to use for all other
205 * key_at_index_* sysfs files.
207 static unsigned int key_at_index;
209 static struct workqueue_struct *applesmc_led_wq;
212 * __wait_status - Wait up to 32ms for the status port to get a certain value
213 * (masked with 0x0f), returning zero if the value is obtained. Callers must
214 * hold applesmc_lock.
216 static int __wait_status(u8 val)
218 int us;
220 val = val & APPLESMC_STATUS_MASK;
222 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
223 udelay(us);
224 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
225 if (debug)
226 printk(KERN_DEBUG
227 "Waited %d us for status %x\n",
228 2 * us - APPLESMC_MIN_WAIT, val);
229 return 0;
233 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
234 val, inb(APPLESMC_CMD_PORT));
236 return -EIO;
240 * special treatment of command port - on newer macbooks, it seems necessary
241 * to resend the command byte before polling the status again. Callers must
242 * hold applesmc_lock.
244 static int send_command(u8 cmd)
246 int us;
247 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
248 outb(cmd, APPLESMC_CMD_PORT);
249 udelay(us);
250 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
251 return 0;
253 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
254 cmd, inb(APPLESMC_CMD_PORT));
255 return -EIO;
259 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
260 * Returns zero on success or a negative error on failure. Callers must
261 * hold applesmc_lock.
263 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
265 int i;
267 if (len > APPLESMC_MAX_DATA_LENGTH) {
268 printk(KERN_ERR "applesmc_read_key: cannot read more than "
269 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
270 return -EINVAL;
273 if (send_command(APPLESMC_READ_CMD))
274 return -EIO;
276 for (i = 0; i < 4; i++) {
277 outb(key[i], APPLESMC_DATA_PORT);
278 if (__wait_status(0x04))
279 return -EIO;
281 if (debug)
282 printk(KERN_DEBUG "<%s", key);
284 outb(len, APPLESMC_DATA_PORT);
285 if (debug)
286 printk(KERN_DEBUG ">%x", len);
288 for (i = 0; i < len; i++) {
289 if (__wait_status(0x05))
290 return -EIO;
291 buffer[i] = inb(APPLESMC_DATA_PORT);
292 if (debug)
293 printk(KERN_DEBUG "<%x", buffer[i]);
295 if (debug)
296 printk(KERN_DEBUG "\n");
298 return 0;
302 * applesmc_write_key - writes len bytes from buffer to a given key.
303 * Returns zero on success or a negative error on failure. Callers must
304 * hold applesmc_lock.
306 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
308 int i;
310 if (len > APPLESMC_MAX_DATA_LENGTH) {
311 printk(KERN_ERR "applesmc_write_key: cannot write more than "
312 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
313 return -EINVAL;
316 if (send_command(APPLESMC_WRITE_CMD))
317 return -EIO;
319 for (i = 0; i < 4; i++) {
320 outb(key[i], APPLESMC_DATA_PORT);
321 if (__wait_status(0x04))
322 return -EIO;
325 outb(len, APPLESMC_DATA_PORT);
327 for (i = 0; i < len; i++) {
328 if (__wait_status(0x04))
329 return -EIO;
330 outb(buffer[i], APPLESMC_DATA_PORT);
333 return 0;
337 * applesmc_get_key_at_index - get key at index, and put the result in key
338 * (char[6]). Returns zero on success or a negative error on failure. Callers
339 * must hold applesmc_lock.
341 static int applesmc_get_key_at_index(int index, char* key)
343 int i;
344 u8 readkey[4];
345 readkey[0] = index >> 24;
346 readkey[1] = index >> 16;
347 readkey[2] = index >> 8;
348 readkey[3] = index;
350 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
351 return -EIO;
353 for (i = 0; i < 4; i++) {
354 outb(readkey[i], APPLESMC_DATA_PORT);
355 if (__wait_status(0x04))
356 return -EIO;
359 outb(4, APPLESMC_DATA_PORT);
361 for (i = 0; i < 4; i++) {
362 if (__wait_status(0x05))
363 return -EIO;
364 key[i] = inb(APPLESMC_DATA_PORT);
366 key[4] = 0;
368 return 0;
372 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
373 * Returns zero on success or a negative error on failure. Callers must
374 * hold applesmc_lock.
376 static int applesmc_get_key_type(char* key, char* type)
378 int i;
380 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
381 return -EIO;
383 for (i = 0; i < 4; i++) {
384 outb(key[i], APPLESMC_DATA_PORT);
385 if (__wait_status(0x04))
386 return -EIO;
389 outb(6, APPLESMC_DATA_PORT);
391 for (i = 0; i < 6; i++) {
392 if (__wait_status(0x05))
393 return -EIO;
394 type[i] = inb(APPLESMC_DATA_PORT);
396 type[5] = 0;
398 return 0;
402 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
403 * hold applesmc_lock.
405 static int applesmc_read_motion_sensor(int index, s16* value)
407 u8 buffer[2];
408 int ret;
410 switch (index) {
411 case SENSOR_X:
412 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
413 break;
414 case SENSOR_Y:
415 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
416 break;
417 case SENSOR_Z:
418 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
419 break;
420 default:
421 ret = -EINVAL;
424 *value = ((s16)buffer[0] << 8) | buffer[1];
426 return ret;
430 * applesmc_device_init - initialize the accelerometer. Returns zero on success
431 * and negative error code on failure. Can sleep.
433 static int applesmc_device_init(void)
435 int total, ret = -ENXIO;
436 u8 buffer[2];
438 if (!applesmc_accelerometer)
439 return 0;
441 mutex_lock(&applesmc_lock);
443 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
444 if (debug)
445 printk(KERN_DEBUG "applesmc try %d\n", total);
446 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
447 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
448 if (total == INIT_TIMEOUT_MSECS) {
449 printk(KERN_DEBUG "applesmc: device has"
450 " already been initialized"
451 " (0x%02x, 0x%02x).\n",
452 buffer[0], buffer[1]);
453 } else {
454 printk(KERN_DEBUG "applesmc: device"
455 " successfully initialized"
456 " (0x%02x, 0x%02x).\n",
457 buffer[0], buffer[1]);
459 ret = 0;
460 goto out;
462 buffer[0] = 0xe0;
463 buffer[1] = 0x00;
464 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
465 msleep(INIT_WAIT_MSECS);
468 printk(KERN_WARNING "applesmc: failed to init the device\n");
470 out:
471 mutex_unlock(&applesmc_lock);
472 return ret;
476 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
477 * applesmc_lock.
479 static int applesmc_get_fan_count(void)
481 int ret;
482 u8 buffer[1];
484 mutex_lock(&applesmc_lock);
486 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
488 mutex_unlock(&applesmc_lock);
489 if (ret)
490 return ret;
491 else
492 return buffer[0];
495 /* Device model stuff */
496 static int applesmc_probe(struct platform_device *dev)
498 int ret;
500 ret = applesmc_device_init();
501 if (ret)
502 return ret;
504 printk(KERN_INFO "applesmc: device successfully initialized.\n");
505 return 0;
508 /* Synchronize device with memorized backlight state */
509 static int applesmc_pm_resume(struct device *dev)
511 mutex_lock(&applesmc_lock);
512 if (applesmc_light)
513 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
514 mutex_unlock(&applesmc_lock);
515 return 0;
518 /* Reinitialize device on resume from hibernation */
519 static int applesmc_pm_restore(struct device *dev)
521 int ret = applesmc_device_init();
522 if (ret)
523 return ret;
524 return applesmc_pm_resume(dev);
527 static const struct dev_pm_ops applesmc_pm_ops = {
528 .resume = applesmc_pm_resume,
529 .restore = applesmc_pm_restore,
532 static struct platform_driver applesmc_driver = {
533 .probe = applesmc_probe,
534 .driver = {
535 .name = "applesmc",
536 .owner = THIS_MODULE,
537 .pm = &applesmc_pm_ops,
542 * applesmc_calibrate - Set our "resting" values. Callers must
543 * hold applesmc_lock.
545 static void applesmc_calibrate(void)
547 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
548 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
549 rest_x = -rest_x;
552 static void applesmc_idev_poll(struct input_polled_dev *dev)
554 struct input_dev *idev = dev->input;
555 s16 x, y;
557 mutex_lock(&applesmc_lock);
559 if (applesmc_read_motion_sensor(SENSOR_X, &x))
560 goto out;
561 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
562 goto out;
564 x = -x;
565 input_report_abs(idev, ABS_X, x - rest_x);
566 input_report_abs(idev, ABS_Y, y - rest_y);
567 input_sync(idev);
569 out:
570 mutex_unlock(&applesmc_lock);
573 /* Sysfs Files */
575 static ssize_t applesmc_name_show(struct device *dev,
576 struct device_attribute *attr, char *buf)
578 return snprintf(buf, PAGE_SIZE, "applesmc\n");
581 static ssize_t applesmc_position_show(struct device *dev,
582 struct device_attribute *attr, char *buf)
584 int ret;
585 s16 x, y, z;
587 mutex_lock(&applesmc_lock);
589 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
590 if (ret)
591 goto out;
592 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
593 if (ret)
594 goto out;
595 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
596 if (ret)
597 goto out;
599 out:
600 mutex_unlock(&applesmc_lock);
601 if (ret)
602 return ret;
603 else
604 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
607 static ssize_t applesmc_light_show(struct device *dev,
608 struct device_attribute *attr, char *sysfsbuf)
610 static int data_length;
611 int ret;
612 u8 left = 0, right = 0;
613 u8 buffer[10], query[6];
615 mutex_lock(&applesmc_lock);
617 if (!data_length) {
618 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
619 if (ret)
620 goto out;
621 data_length = clamp_val(query[0], 0, 10);
622 printk(KERN_INFO "applesmc: light sensor data length set to "
623 "%d\n", data_length);
626 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
627 /* newer macbooks report a single 10-bit bigendian value */
628 if (data_length == 10) {
629 left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2;
630 goto out;
632 left = buffer[2];
633 if (ret)
634 goto out;
635 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
636 right = buffer[2];
638 out:
639 mutex_unlock(&applesmc_lock);
640 if (ret)
641 return ret;
642 else
643 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
646 /* Displays degree Celsius * 1000 */
647 static ssize_t applesmc_show_temperature(struct device *dev,
648 struct device_attribute *devattr, char *sysfsbuf)
650 int ret;
651 u8 buffer[2];
652 unsigned int temp;
653 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
654 const char* key =
655 temperature_sensors_sets[applesmc_temperature_set][attr->index];
657 mutex_lock(&applesmc_lock);
659 ret = applesmc_read_key(key, buffer, 2);
660 temp = buffer[0]*1000;
661 temp += (buffer[1] >> 6) * 250;
663 mutex_unlock(&applesmc_lock);
665 if (ret)
666 return ret;
667 else
668 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
671 static ssize_t applesmc_show_fan_speed(struct device *dev,
672 struct device_attribute *attr, char *sysfsbuf)
674 int ret;
675 unsigned int speed = 0;
676 char newkey[5];
677 u8 buffer[2];
678 struct sensor_device_attribute_2 *sensor_attr =
679 to_sensor_dev_attr_2(attr);
681 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
682 newkey[1] = '0' + sensor_attr->index;
683 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
684 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
685 newkey[4] = 0;
687 mutex_lock(&applesmc_lock);
689 ret = applesmc_read_key(newkey, buffer, 2);
690 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
692 mutex_unlock(&applesmc_lock);
693 if (ret)
694 return ret;
695 else
696 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
699 static ssize_t applesmc_store_fan_speed(struct device *dev,
700 struct device_attribute *attr,
701 const char *sysfsbuf, size_t count)
703 int ret;
704 u32 speed;
705 char newkey[5];
706 u8 buffer[2];
707 struct sensor_device_attribute_2 *sensor_attr =
708 to_sensor_dev_attr_2(attr);
710 speed = simple_strtoul(sysfsbuf, NULL, 10);
712 if (speed > 0x4000) /* Bigger than a 14-bit value */
713 return -EINVAL;
715 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
716 newkey[1] = '0' + sensor_attr->index;
717 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
718 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
719 newkey[4] = 0;
721 mutex_lock(&applesmc_lock);
723 buffer[0] = (speed >> 6) & 0xff;
724 buffer[1] = (speed << 2) & 0xff;
725 ret = applesmc_write_key(newkey, buffer, 2);
727 mutex_unlock(&applesmc_lock);
728 if (ret)
729 return ret;
730 else
731 return count;
734 static ssize_t applesmc_show_fan_manual(struct device *dev,
735 struct device_attribute *devattr, char *sysfsbuf)
737 int ret;
738 u16 manual = 0;
739 u8 buffer[2];
740 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
742 mutex_lock(&applesmc_lock);
744 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
745 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
747 mutex_unlock(&applesmc_lock);
748 if (ret)
749 return ret;
750 else
751 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
754 static ssize_t applesmc_store_fan_manual(struct device *dev,
755 struct device_attribute *devattr,
756 const char *sysfsbuf, size_t count)
758 int ret;
759 u8 buffer[2];
760 u32 input;
761 u16 val;
762 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
764 input = simple_strtoul(sysfsbuf, NULL, 10);
766 mutex_lock(&applesmc_lock);
768 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
769 val = (buffer[0] << 8 | buffer[1]);
770 if (ret)
771 goto out;
773 if (input)
774 val = val | (0x01 << attr->index);
775 else
776 val = val & ~(0x01 << attr->index);
778 buffer[0] = (val >> 8) & 0xFF;
779 buffer[1] = val & 0xFF;
781 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
783 out:
784 mutex_unlock(&applesmc_lock);
785 if (ret)
786 return ret;
787 else
788 return count;
791 static ssize_t applesmc_show_fan_position(struct device *dev,
792 struct device_attribute *attr, char *sysfsbuf)
794 int ret;
795 char newkey[5];
796 u8 buffer[17];
797 struct sensor_device_attribute_2 *sensor_attr =
798 to_sensor_dev_attr_2(attr);
800 newkey[0] = FAN_POSITION[0];
801 newkey[1] = '0' + sensor_attr->index;
802 newkey[2] = FAN_POSITION[2];
803 newkey[3] = FAN_POSITION[3];
804 newkey[4] = 0;
806 mutex_lock(&applesmc_lock);
808 ret = applesmc_read_key(newkey, buffer, 16);
809 buffer[16] = 0;
811 mutex_unlock(&applesmc_lock);
812 if (ret)
813 return ret;
814 else
815 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
818 static ssize_t applesmc_calibrate_show(struct device *dev,
819 struct device_attribute *attr, char *sysfsbuf)
821 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
824 static ssize_t applesmc_calibrate_store(struct device *dev,
825 struct device_attribute *attr, const char *sysfsbuf, size_t count)
827 mutex_lock(&applesmc_lock);
828 applesmc_calibrate();
829 mutex_unlock(&applesmc_lock);
831 return count;
834 static void applesmc_backlight_set(struct work_struct *work)
836 mutex_lock(&applesmc_lock);
837 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
838 mutex_unlock(&applesmc_lock);
840 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
842 static void applesmc_brightness_set(struct led_classdev *led_cdev,
843 enum led_brightness value)
845 int ret;
847 backlight_state[0] = value;
848 ret = queue_work(applesmc_led_wq, &backlight_work);
850 if (debug && (!ret))
851 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
854 static ssize_t applesmc_key_count_show(struct device *dev,
855 struct device_attribute *attr, char *sysfsbuf)
857 int ret;
858 u8 buffer[4];
859 u32 count;
861 mutex_lock(&applesmc_lock);
863 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
864 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
865 ((u32)buffer[2]<<8) + buffer[3];
867 mutex_unlock(&applesmc_lock);
868 if (ret)
869 return ret;
870 else
871 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
874 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
875 struct device_attribute *attr, char *sysfsbuf)
877 char key[5];
878 char info[6];
879 int ret;
881 mutex_lock(&applesmc_lock);
883 ret = applesmc_get_key_at_index(key_at_index, key);
885 if (ret || !key[0]) {
886 mutex_unlock(&applesmc_lock);
888 return -EINVAL;
891 ret = applesmc_get_key_type(key, info);
893 if (ret) {
894 mutex_unlock(&applesmc_lock);
896 return ret;
900 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
901 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
903 ret = applesmc_read_key(key, sysfsbuf, info[0]);
905 mutex_unlock(&applesmc_lock);
907 if (!ret) {
908 return info[0];
909 } else {
910 return ret;
914 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
915 struct device_attribute *attr, char *sysfsbuf)
917 char key[5];
918 char info[6];
919 int ret;
921 mutex_lock(&applesmc_lock);
923 ret = applesmc_get_key_at_index(key_at_index, key);
925 if (ret || !key[0]) {
926 mutex_unlock(&applesmc_lock);
928 return -EINVAL;
931 ret = applesmc_get_key_type(key, info);
933 mutex_unlock(&applesmc_lock);
935 if (!ret)
936 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
937 else
938 return ret;
941 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
942 struct device_attribute *attr, char *sysfsbuf)
944 char key[5];
945 char info[6];
946 int ret;
948 mutex_lock(&applesmc_lock);
950 ret = applesmc_get_key_at_index(key_at_index, key);
952 if (ret || !key[0]) {
953 mutex_unlock(&applesmc_lock);
955 return -EINVAL;
958 ret = applesmc_get_key_type(key, info);
960 mutex_unlock(&applesmc_lock);
962 if (!ret)
963 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
964 else
965 return ret;
968 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
969 struct device_attribute *attr, char *sysfsbuf)
971 char key[5];
972 int ret;
974 mutex_lock(&applesmc_lock);
976 ret = applesmc_get_key_at_index(key_at_index, key);
978 mutex_unlock(&applesmc_lock);
980 if (!ret && key[0])
981 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
982 else
983 return -EINVAL;
986 static ssize_t applesmc_key_at_index_show(struct device *dev,
987 struct device_attribute *attr, char *sysfsbuf)
989 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
992 static ssize_t applesmc_key_at_index_store(struct device *dev,
993 struct device_attribute *attr, const char *sysfsbuf, size_t count)
995 mutex_lock(&applesmc_lock);
997 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
999 mutex_unlock(&applesmc_lock);
1001 return count;
1004 static struct led_classdev applesmc_backlight = {
1005 .name = "smc::kbd_backlight",
1006 .default_trigger = "nand-disk",
1007 .brightness_set = applesmc_brightness_set,
1010 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
1012 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
1013 static DEVICE_ATTR(calibrate, 0644,
1014 applesmc_calibrate_show, applesmc_calibrate_store);
1016 static struct attribute *accelerometer_attributes[] = {
1017 &dev_attr_position.attr,
1018 &dev_attr_calibrate.attr,
1019 NULL
1022 static const struct attribute_group accelerometer_attributes_group =
1023 { .attrs = accelerometer_attributes };
1025 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
1027 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
1028 static DEVICE_ATTR(key_at_index, 0644,
1029 applesmc_key_at_index_show, applesmc_key_at_index_store);
1030 static DEVICE_ATTR(key_at_index_name, 0444,
1031 applesmc_key_at_index_name_show, NULL);
1032 static DEVICE_ATTR(key_at_index_type, 0444,
1033 applesmc_key_at_index_type_show, NULL);
1034 static DEVICE_ATTR(key_at_index_data_length, 0444,
1035 applesmc_key_at_index_data_length_show, NULL);
1036 static DEVICE_ATTR(key_at_index_data, 0444,
1037 applesmc_key_at_index_read_show, NULL);
1039 static struct attribute *key_enumeration_attributes[] = {
1040 &dev_attr_key_count.attr,
1041 &dev_attr_key_at_index.attr,
1042 &dev_attr_key_at_index_name.attr,
1043 &dev_attr_key_at_index_type.attr,
1044 &dev_attr_key_at_index_data_length.attr,
1045 &dev_attr_key_at_index_data.attr,
1046 NULL
1049 static const struct attribute_group key_enumeration_group =
1050 { .attrs = key_enumeration_attributes };
1053 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1054 * - show actual speed
1055 * - show/store minimum speed
1056 * - show maximum speed
1057 * - show safe speed
1058 * - show/store target speed
1059 * - show/store manual mode
1061 #define sysfs_fan_speeds_offset(offset) \
1062 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1063 applesmc_show_fan_speed, NULL, 0, offset-1); \
1065 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1066 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1068 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1069 applesmc_show_fan_speed, NULL, 2, offset-1); \
1071 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1072 applesmc_show_fan_speed, NULL, 3, offset-1); \
1074 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1075 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1077 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1078 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1080 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1081 applesmc_show_fan_position, NULL, offset-1); \
1083 static struct attribute *fan##offset##_attributes[] = { \
1084 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1085 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1086 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1087 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1088 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1089 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1090 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1091 NULL \
1095 * Create the needed functions for each fan using the macro defined above
1096 * (4 fans are supported)
1098 sysfs_fan_speeds_offset(1);
1099 sysfs_fan_speeds_offset(2);
1100 sysfs_fan_speeds_offset(3);
1101 sysfs_fan_speeds_offset(4);
1103 static const struct attribute_group fan_attribute_groups[] = {
1104 { .attrs = fan1_attributes },
1105 { .attrs = fan2_attributes },
1106 { .attrs = fan3_attributes },
1107 { .attrs = fan4_attributes },
1111 * Temperature sensors sysfs entries.
1113 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1114 applesmc_show_temperature, NULL, 0);
1115 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1116 applesmc_show_temperature, NULL, 1);
1117 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1118 applesmc_show_temperature, NULL, 2);
1119 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1120 applesmc_show_temperature, NULL, 3);
1121 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1122 applesmc_show_temperature, NULL, 4);
1123 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1124 applesmc_show_temperature, NULL, 5);
1125 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1126 applesmc_show_temperature, NULL, 6);
1127 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1128 applesmc_show_temperature, NULL, 7);
1129 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1130 applesmc_show_temperature, NULL, 8);
1131 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1132 applesmc_show_temperature, NULL, 9);
1133 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1134 applesmc_show_temperature, NULL, 10);
1135 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1136 applesmc_show_temperature, NULL, 11);
1137 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1138 applesmc_show_temperature, NULL, 12);
1139 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1140 applesmc_show_temperature, NULL, 13);
1141 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1142 applesmc_show_temperature, NULL, 14);
1143 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1144 applesmc_show_temperature, NULL, 15);
1145 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1146 applesmc_show_temperature, NULL, 16);
1147 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1148 applesmc_show_temperature, NULL, 17);
1149 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1150 applesmc_show_temperature, NULL, 18);
1151 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1152 applesmc_show_temperature, NULL, 19);
1153 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1154 applesmc_show_temperature, NULL, 20);
1155 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1156 applesmc_show_temperature, NULL, 21);
1157 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1158 applesmc_show_temperature, NULL, 22);
1159 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1160 applesmc_show_temperature, NULL, 23);
1161 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1162 applesmc_show_temperature, NULL, 24);
1163 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1164 applesmc_show_temperature, NULL, 25);
1165 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1166 applesmc_show_temperature, NULL, 26);
1167 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1168 applesmc_show_temperature, NULL, 27);
1169 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1170 applesmc_show_temperature, NULL, 28);
1171 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1172 applesmc_show_temperature, NULL, 29);
1173 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1174 applesmc_show_temperature, NULL, 30);
1175 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1176 applesmc_show_temperature, NULL, 31);
1177 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1178 applesmc_show_temperature, NULL, 32);
1179 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1180 applesmc_show_temperature, NULL, 33);
1181 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1182 applesmc_show_temperature, NULL, 34);
1183 static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
1184 applesmc_show_temperature, NULL, 35);
1185 static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
1186 applesmc_show_temperature, NULL, 36);
1187 static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
1188 applesmc_show_temperature, NULL, 37);
1189 static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
1190 applesmc_show_temperature, NULL, 38);
1191 static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
1192 applesmc_show_temperature, NULL, 39);
1194 static struct attribute *temperature_attributes[] = {
1195 &sensor_dev_attr_temp1_input.dev_attr.attr,
1196 &sensor_dev_attr_temp2_input.dev_attr.attr,
1197 &sensor_dev_attr_temp3_input.dev_attr.attr,
1198 &sensor_dev_attr_temp4_input.dev_attr.attr,
1199 &sensor_dev_attr_temp5_input.dev_attr.attr,
1200 &sensor_dev_attr_temp6_input.dev_attr.attr,
1201 &sensor_dev_attr_temp7_input.dev_attr.attr,
1202 &sensor_dev_attr_temp8_input.dev_attr.attr,
1203 &sensor_dev_attr_temp9_input.dev_attr.attr,
1204 &sensor_dev_attr_temp10_input.dev_attr.attr,
1205 &sensor_dev_attr_temp11_input.dev_attr.attr,
1206 &sensor_dev_attr_temp12_input.dev_attr.attr,
1207 &sensor_dev_attr_temp13_input.dev_attr.attr,
1208 &sensor_dev_attr_temp14_input.dev_attr.attr,
1209 &sensor_dev_attr_temp15_input.dev_attr.attr,
1210 &sensor_dev_attr_temp16_input.dev_attr.attr,
1211 &sensor_dev_attr_temp17_input.dev_attr.attr,
1212 &sensor_dev_attr_temp18_input.dev_attr.attr,
1213 &sensor_dev_attr_temp19_input.dev_attr.attr,
1214 &sensor_dev_attr_temp20_input.dev_attr.attr,
1215 &sensor_dev_attr_temp21_input.dev_attr.attr,
1216 &sensor_dev_attr_temp22_input.dev_attr.attr,
1217 &sensor_dev_attr_temp23_input.dev_attr.attr,
1218 &sensor_dev_attr_temp24_input.dev_attr.attr,
1219 &sensor_dev_attr_temp25_input.dev_attr.attr,
1220 &sensor_dev_attr_temp26_input.dev_attr.attr,
1221 &sensor_dev_attr_temp27_input.dev_attr.attr,
1222 &sensor_dev_attr_temp28_input.dev_attr.attr,
1223 &sensor_dev_attr_temp29_input.dev_attr.attr,
1224 &sensor_dev_attr_temp30_input.dev_attr.attr,
1225 &sensor_dev_attr_temp31_input.dev_attr.attr,
1226 &sensor_dev_attr_temp32_input.dev_attr.attr,
1227 &sensor_dev_attr_temp33_input.dev_attr.attr,
1228 &sensor_dev_attr_temp34_input.dev_attr.attr,
1229 &sensor_dev_attr_temp35_input.dev_attr.attr,
1230 &sensor_dev_attr_temp36_input.dev_attr.attr,
1231 &sensor_dev_attr_temp37_input.dev_attr.attr,
1232 &sensor_dev_attr_temp38_input.dev_attr.attr,
1233 &sensor_dev_attr_temp39_input.dev_attr.attr,
1234 &sensor_dev_attr_temp40_input.dev_attr.attr,
1235 NULL
1238 static const struct attribute_group temperature_attributes_group =
1239 { .attrs = temperature_attributes };
1241 /* Module stuff */
1244 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1246 static int applesmc_dmi_match(const struct dmi_system_id *id)
1248 int i = 0;
1249 struct dmi_match_data* dmi_data = id->driver_data;
1250 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1251 applesmc_accelerometer = dmi_data->accelerometer;
1252 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1253 applesmc_accelerometer ? "with" : "without");
1254 applesmc_light = dmi_data->light;
1255 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1256 applesmc_light ? "with" : "without");
1258 applesmc_temperature_set = dmi_data->temperature_set;
1259 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1260 i++;
1261 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1262 return 1;
1265 /* Create accelerometer ressources */
1266 static int applesmc_create_accelerometer(void)
1268 struct input_dev *idev;
1269 int ret;
1271 ret = sysfs_create_group(&pdev->dev.kobj,
1272 &accelerometer_attributes_group);
1273 if (ret)
1274 goto out;
1276 applesmc_idev = input_allocate_polled_device();
1277 if (!applesmc_idev) {
1278 ret = -ENOMEM;
1279 goto out_sysfs;
1282 applesmc_idev->poll = applesmc_idev_poll;
1283 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1285 /* initial calibrate for the input device */
1286 applesmc_calibrate();
1288 /* initialize the input device */
1289 idev = applesmc_idev->input;
1290 idev->name = "applesmc";
1291 idev->id.bustype = BUS_HOST;
1292 idev->dev.parent = &pdev->dev;
1293 idev->evbit[0] = BIT_MASK(EV_ABS);
1294 input_set_abs_params(idev, ABS_X,
1295 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1296 input_set_abs_params(idev, ABS_Y,
1297 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1299 ret = input_register_polled_device(applesmc_idev);
1300 if (ret)
1301 goto out_idev;
1303 return 0;
1305 out_idev:
1306 input_free_polled_device(applesmc_idev);
1308 out_sysfs:
1309 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1311 out:
1312 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1313 return ret;
1316 /* Release all ressources used by the accelerometer */
1317 static void applesmc_release_accelerometer(void)
1319 input_unregister_polled_device(applesmc_idev);
1320 input_free_polled_device(applesmc_idev);
1321 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1324 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1325 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1326 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1327 /* MacBook2: accelerometer and temperature set 1 */
1328 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1329 /* MacBook: accelerometer and temperature set 2 */
1330 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1331 /* MacMini: temperature set 3 */
1332 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1333 /* MacPro: temperature set 4 */
1334 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1335 /* iMac: temperature set 5 */
1336 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1337 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1338 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1339 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1340 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1341 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1342 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1343 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1344 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1345 /* iMac 5: light sensor only, temperature set 10 */
1346 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1347 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1348 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
1349 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1350 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
1351 /* iMac 8: light sensor only, temperature set 13 */
1352 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
1353 /* iMac 6: light sensor only, temperature set 14 */
1354 { .accelerometer = 0, .light = 0, .temperature_set = 14 },
1355 /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
1356 { .accelerometer = 1, .light = 1, .temperature_set = 15 },
1357 /* MacPro3,1: temperature set 16 */
1358 { .accelerometer = 0, .light = 0, .temperature_set = 16 },
1359 /* iMac 9,1: light sensor only, temperature set 17 */
1360 { .accelerometer = 0, .light = 0, .temperature_set = 17 },
1361 /* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
1362 { .accelerometer = 1, .light = 1, .temperature_set = 18 },
1365 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1366 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1367 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1368 { applesmc_dmi_match, "Apple MacBook Air 2", {
1369 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1370 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
1371 &applesmc_dmi_data[15]},
1372 { applesmc_dmi_match, "Apple MacBook Air", {
1373 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1374 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1375 &applesmc_dmi_data[7]},
1376 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1377 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1378 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1379 &applesmc_dmi_data[12]},
1380 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1381 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1382 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1383 &applesmc_dmi_data[8]},
1384 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1385 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1386 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1387 &applesmc_dmi_data[9]},
1388 { applesmc_dmi_match, "Apple MacBook Pro 2,2", {
1389 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
1390 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
1391 &applesmc_dmi_data[18]},
1392 { applesmc_dmi_match, "Apple MacBook Pro", {
1393 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1394 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1395 &applesmc_dmi_data[0]},
1396 { applesmc_dmi_match, "Apple MacBook (v2)", {
1397 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1398 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1399 &applesmc_dmi_data[1]},
1400 { applesmc_dmi_match, "Apple MacBook (v3)", {
1401 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1402 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1403 &applesmc_dmi_data[6]},
1404 { applesmc_dmi_match, "Apple MacBook 4", {
1405 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1406 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1407 &applesmc_dmi_data[6]},
1408 { applesmc_dmi_match, "Apple MacBook 5", {
1409 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1410 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1411 &applesmc_dmi_data[11]},
1412 { applesmc_dmi_match, "Apple MacBook", {
1413 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1414 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1415 &applesmc_dmi_data[2]},
1416 { applesmc_dmi_match, "Apple Macmini", {
1417 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1418 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1419 &applesmc_dmi_data[3]},
1420 { applesmc_dmi_match, "Apple MacPro2", {
1421 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1422 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1423 &applesmc_dmi_data[4]},
1424 { applesmc_dmi_match, "Apple MacPro3", {
1425 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1426 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") },
1427 &applesmc_dmi_data[16]},
1428 { applesmc_dmi_match, "Apple MacPro", {
1429 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1430 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1431 &applesmc_dmi_data[4]},
1432 { applesmc_dmi_match, "Apple iMac 9,1", {
1433 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
1434 DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
1435 &applesmc_dmi_data[17]},
1436 { applesmc_dmi_match, "Apple iMac 8", {
1437 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1438 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1439 &applesmc_dmi_data[13]},
1440 { applesmc_dmi_match, "Apple iMac 6", {
1441 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1442 DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
1443 &applesmc_dmi_data[14]},
1444 { applesmc_dmi_match, "Apple iMac 5", {
1445 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1446 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1447 &applesmc_dmi_data[10]},
1448 { applesmc_dmi_match, "Apple iMac", {
1449 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1450 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1451 &applesmc_dmi_data[5]},
1452 { .ident = NULL }
1455 static int __init applesmc_init(void)
1457 int ret;
1458 int count;
1459 int i;
1461 if (!dmi_check_system(applesmc_whitelist)) {
1462 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1463 ret = -ENODEV;
1464 goto out;
1467 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1468 "applesmc")) {
1469 ret = -ENXIO;
1470 goto out;
1473 ret = platform_driver_register(&applesmc_driver);
1474 if (ret)
1475 goto out_region;
1477 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1478 NULL, 0);
1479 if (IS_ERR(pdev)) {
1480 ret = PTR_ERR(pdev);
1481 goto out_driver;
1484 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1485 if (ret)
1486 goto out_device;
1488 /* Create key enumeration sysfs files */
1489 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1490 if (ret)
1491 goto out_name;
1493 /* create fan files */
1494 count = applesmc_get_fan_count();
1495 if (count < 0) {
1496 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1497 } else {
1498 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1500 switch (count) {
1501 default:
1502 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1503 " but at most 4 fans are supported"
1504 " by the driver.\n");
1505 case 4:
1506 ret = sysfs_create_group(&pdev->dev.kobj,
1507 &fan_attribute_groups[3]);
1508 if (ret)
1509 goto out_key_enumeration;
1510 case 3:
1511 ret = sysfs_create_group(&pdev->dev.kobj,
1512 &fan_attribute_groups[2]);
1513 if (ret)
1514 goto out_key_enumeration;
1515 case 2:
1516 ret = sysfs_create_group(&pdev->dev.kobj,
1517 &fan_attribute_groups[1]);
1518 if (ret)
1519 goto out_key_enumeration;
1520 case 1:
1521 ret = sysfs_create_group(&pdev->dev.kobj,
1522 &fan_attribute_groups[0]);
1523 if (ret)
1524 goto out_fan_1;
1525 case 0:
1530 for (i = 0;
1531 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1532 i++) {
1533 if (temperature_attributes[i] == NULL) {
1534 printk(KERN_ERR "applesmc: More temperature sensors "
1535 "in temperature_sensors_sets (at least %i)"
1536 "than available sysfs files in "
1537 "temperature_attributes (%i), please report "
1538 "this bug.\n", i, i-1);
1539 goto out_temperature;
1541 ret = sysfs_create_file(&pdev->dev.kobj,
1542 temperature_attributes[i]);
1543 if (ret)
1544 goto out_temperature;
1547 if (applesmc_accelerometer) {
1548 ret = applesmc_create_accelerometer();
1549 if (ret)
1550 goto out_temperature;
1553 if (applesmc_light) {
1554 /* Add light sensor file */
1555 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1556 if (ret)
1557 goto out_accelerometer;
1559 /* Create the workqueue */
1560 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1561 if (!applesmc_led_wq) {
1562 ret = -ENOMEM;
1563 goto out_light_sysfs;
1566 /* register as a led device */
1567 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1568 if (ret < 0)
1569 goto out_light_wq;
1572 hwmon_dev = hwmon_device_register(&pdev->dev);
1573 if (IS_ERR(hwmon_dev)) {
1574 ret = PTR_ERR(hwmon_dev);
1575 goto out_light_ledclass;
1578 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1580 return 0;
1582 out_light_ledclass:
1583 if (applesmc_light)
1584 led_classdev_unregister(&applesmc_backlight);
1585 out_light_wq:
1586 if (applesmc_light)
1587 destroy_workqueue(applesmc_led_wq);
1588 out_light_sysfs:
1589 if (applesmc_light)
1590 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1591 out_accelerometer:
1592 if (applesmc_accelerometer)
1593 applesmc_release_accelerometer();
1594 out_temperature:
1595 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1596 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1597 out_fan_1:
1598 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1599 out_key_enumeration:
1600 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1601 out_name:
1602 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1603 out_device:
1604 platform_device_unregister(pdev);
1605 out_driver:
1606 platform_driver_unregister(&applesmc_driver);
1607 out_region:
1608 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1609 out:
1610 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1611 return ret;
1614 static void __exit applesmc_exit(void)
1616 hwmon_device_unregister(hwmon_dev);
1617 if (applesmc_light) {
1618 led_classdev_unregister(&applesmc_backlight);
1619 destroy_workqueue(applesmc_led_wq);
1620 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1622 if (applesmc_accelerometer)
1623 applesmc_release_accelerometer();
1624 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1625 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1626 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1627 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1628 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1629 platform_device_unregister(pdev);
1630 platform_driver_unregister(&applesmc_driver);
1631 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1633 printk(KERN_INFO "applesmc: driver unloaded.\n");
1636 module_init(applesmc_init);
1637 module_exit(applesmc_exit);
1639 MODULE_AUTHOR("Nicolas Boichat");
1640 MODULE_DESCRIPTION("Apple SMC");
1641 MODULE_LICENSE("GPL v2");
1642 MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);