ACPI: thinkpad-acpi: add development version tag
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / hwmon / applesmc.c
blobf69f930e5e21a256794683864f2b8c842a004a69
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 },
151 /* Set 19: Macbook Pro 5,3 */
152 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D",
153 "TG0F", "TG0H", "TG0P", "TG0T", "TN0D", "TN0P", "TTF0", "Th2H",
154 "Tm0P", "Ts0P", "Ts0S", NULL },
155 /* Set 20: MacBook Pro 5,4 */
156 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TN0D",
157 "TN0P", "TTF0", "Th2H", "Ts0P", "Ts0S", NULL },
158 /* Set 21: MacBook Pro 6,2 */
159 { "TB0T", "TB1T", "TB2T", "TC0C", "TC0D", "TC0P", "TC1C", "TG0D",
160 "TG0P", "TG0T", "TMCD", "TP0P", "TPCD", "Th1H", "Th2H", "Tm0P",
161 "Ts0P", "Ts0S", NULL },
162 /* Set 22: MacBook Pro 7,1 */
163 { "TB0T", "TB1T", "TB2T", "TC0D", "TC0P", "TN0D", "TN0P", "TN0S",
164 "TN1D", "TN1F", "TN1G", "TN1S", "Th1H", "Ts0P", "Ts0S", NULL },
165 /* Set 23: MacBook Air 3,1 */
166 { "TB0T", "TB1T", "TB2T", "TC0D", "TC0E", "TC0P", "TC1E", "TCZ3",
167 "TCZ4", "TCZ5", "TG0E", "TG1E", "TG2E", "TGZ3", "TGZ4", "TGZ5",
168 "TH0F", "TH0O", "TM0P" },
171 /* List of keys used to read/write fan speeds */
172 static const char* fan_speed_keys[] = {
173 FAN_ACTUAL_SPEED,
174 FAN_MIN_SPEED,
175 FAN_MAX_SPEED,
176 FAN_SAFE_SPEED,
177 FAN_TARGET_SPEED
180 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
181 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
183 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
184 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
185 #define APPLESMC_INPUT_FLAT 4
187 #define SENSOR_X 0
188 #define SENSOR_Y 1
189 #define SENSOR_Z 2
191 /* Structure to be passed to DMI_MATCH function */
192 struct dmi_match_data {
193 /* Indicates whether this computer has an accelerometer. */
194 int accelerometer;
195 /* Indicates whether this computer has light sensors and keyboard backlight. */
196 int light;
197 /* Indicates which temperature sensors set to use. */
198 int temperature_set;
201 static const int debug;
202 static struct platform_device *pdev;
203 static s16 rest_x;
204 static s16 rest_y;
205 static u8 backlight_state[2];
207 static struct device *hwmon_dev;
208 static struct input_polled_dev *applesmc_idev;
210 /* Indicates whether this computer has an accelerometer. */
211 static unsigned int applesmc_accelerometer;
213 /* Indicates whether this computer has light sensors and keyboard backlight. */
214 static unsigned int applesmc_light;
216 /* Indicates which temperature sensors set to use. */
217 static unsigned int applesmc_temperature_set;
219 static DEFINE_MUTEX(applesmc_lock);
222 * Last index written to key_at_index sysfs file, and value to use for all other
223 * key_at_index_* sysfs files.
225 static unsigned int key_at_index;
227 static struct workqueue_struct *applesmc_led_wq;
230 * __wait_status - Wait up to 32ms for the status port to get a certain value
231 * (masked with 0x0f), returning zero if the value is obtained. Callers must
232 * hold applesmc_lock.
234 static int __wait_status(u8 val)
236 int us;
238 val = val & APPLESMC_STATUS_MASK;
240 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
241 udelay(us);
242 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
243 if (debug)
244 printk(KERN_DEBUG
245 "Waited %d us for status %x\n",
246 2 * us - APPLESMC_MIN_WAIT, val);
247 return 0;
251 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
252 val, inb(APPLESMC_CMD_PORT));
254 return -EIO;
258 * special treatment of command port - on newer macbooks, it seems necessary
259 * to resend the command byte before polling the status again. Callers must
260 * hold applesmc_lock.
262 static int send_command(u8 cmd)
264 int us;
265 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
266 outb(cmd, APPLESMC_CMD_PORT);
267 udelay(us);
268 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
269 return 0;
271 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
272 cmd, inb(APPLESMC_CMD_PORT));
273 return -EIO;
277 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
278 * Returns zero on success or a negative error on failure. Callers must
279 * hold applesmc_lock.
281 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
283 int i;
285 if (len > APPLESMC_MAX_DATA_LENGTH) {
286 printk(KERN_ERR "applesmc_read_key: cannot read more than "
287 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
288 return -EINVAL;
291 if (send_command(APPLESMC_READ_CMD))
292 return -EIO;
294 for (i = 0; i < 4; i++) {
295 outb(key[i], APPLESMC_DATA_PORT);
296 if (__wait_status(0x04))
297 return -EIO;
299 if (debug)
300 printk(KERN_DEBUG "<%s", key);
302 outb(len, APPLESMC_DATA_PORT);
303 if (debug)
304 printk(KERN_DEBUG ">%x", len);
306 for (i = 0; i < len; i++) {
307 if (__wait_status(0x05))
308 return -EIO;
309 buffer[i] = inb(APPLESMC_DATA_PORT);
310 if (debug)
311 printk(KERN_DEBUG "<%x", buffer[i]);
313 if (debug)
314 printk(KERN_DEBUG "\n");
316 return 0;
320 * applesmc_write_key - writes len bytes from buffer to a given key.
321 * Returns zero on success or a negative error on failure. Callers must
322 * hold applesmc_lock.
324 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
326 int i;
328 if (len > APPLESMC_MAX_DATA_LENGTH) {
329 printk(KERN_ERR "applesmc_write_key: cannot write more than "
330 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
331 return -EINVAL;
334 if (send_command(APPLESMC_WRITE_CMD))
335 return -EIO;
337 for (i = 0; i < 4; i++) {
338 outb(key[i], APPLESMC_DATA_PORT);
339 if (__wait_status(0x04))
340 return -EIO;
343 outb(len, APPLESMC_DATA_PORT);
345 for (i = 0; i < len; i++) {
346 if (__wait_status(0x04))
347 return -EIO;
348 outb(buffer[i], APPLESMC_DATA_PORT);
351 return 0;
355 * applesmc_get_key_at_index - get key at index, and put the result in key
356 * (char[6]). Returns zero on success or a negative error on failure. Callers
357 * must hold applesmc_lock.
359 static int applesmc_get_key_at_index(int index, char* key)
361 int i;
362 u8 readkey[4];
363 readkey[0] = index >> 24;
364 readkey[1] = index >> 16;
365 readkey[2] = index >> 8;
366 readkey[3] = index;
368 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
369 return -EIO;
371 for (i = 0; i < 4; i++) {
372 outb(readkey[i], APPLESMC_DATA_PORT);
373 if (__wait_status(0x04))
374 return -EIO;
377 outb(4, APPLESMC_DATA_PORT);
379 for (i = 0; i < 4; i++) {
380 if (__wait_status(0x05))
381 return -EIO;
382 key[i] = inb(APPLESMC_DATA_PORT);
384 key[4] = 0;
386 return 0;
390 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
391 * Returns zero on success or a negative error on failure. Callers must
392 * hold applesmc_lock.
394 static int applesmc_get_key_type(char* key, char* type)
396 int i;
398 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
399 return -EIO;
401 for (i = 0; i < 4; i++) {
402 outb(key[i], APPLESMC_DATA_PORT);
403 if (__wait_status(0x04))
404 return -EIO;
407 outb(6, APPLESMC_DATA_PORT);
409 for (i = 0; i < 6; i++) {
410 if (__wait_status(0x05))
411 return -EIO;
412 type[i] = inb(APPLESMC_DATA_PORT);
414 type[5] = 0;
416 return 0;
420 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
421 * hold applesmc_lock.
423 static int applesmc_read_motion_sensor(int index, s16* value)
425 u8 buffer[2];
426 int ret;
428 switch (index) {
429 case SENSOR_X:
430 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
431 break;
432 case SENSOR_Y:
433 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
434 break;
435 case SENSOR_Z:
436 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
437 break;
438 default:
439 ret = -EINVAL;
442 *value = ((s16)buffer[0] << 8) | buffer[1];
444 return ret;
448 * applesmc_device_init - initialize the accelerometer. Returns zero on success
449 * and negative error code on failure. Can sleep.
451 static int applesmc_device_init(void)
453 int total, ret = -ENXIO;
454 u8 buffer[2];
456 if (!applesmc_accelerometer)
457 return 0;
459 mutex_lock(&applesmc_lock);
461 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
462 if (debug)
463 printk(KERN_DEBUG "applesmc try %d\n", total);
464 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
465 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
466 if (total == INIT_TIMEOUT_MSECS) {
467 printk(KERN_DEBUG "applesmc: device has"
468 " already been initialized"
469 " (0x%02x, 0x%02x).\n",
470 buffer[0], buffer[1]);
471 } else {
472 printk(KERN_DEBUG "applesmc: device"
473 " successfully initialized"
474 " (0x%02x, 0x%02x).\n",
475 buffer[0], buffer[1]);
477 ret = 0;
478 goto out;
480 buffer[0] = 0xe0;
481 buffer[1] = 0x00;
482 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
483 msleep(INIT_WAIT_MSECS);
486 printk(KERN_WARNING "applesmc: failed to init the device\n");
488 out:
489 mutex_unlock(&applesmc_lock);
490 return ret;
494 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
495 * applesmc_lock.
497 static int applesmc_get_fan_count(void)
499 int ret;
500 u8 buffer[1];
502 mutex_lock(&applesmc_lock);
504 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
506 mutex_unlock(&applesmc_lock);
507 if (ret)
508 return ret;
509 else
510 return buffer[0];
513 /* Device model stuff */
514 static int applesmc_probe(struct platform_device *dev)
516 int ret;
518 ret = applesmc_device_init();
519 if (ret)
520 return ret;
522 printk(KERN_INFO "applesmc: device successfully initialized.\n");
523 return 0;
526 /* Synchronize device with memorized backlight state */
527 static int applesmc_pm_resume(struct device *dev)
529 mutex_lock(&applesmc_lock);
530 if (applesmc_light)
531 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
532 mutex_unlock(&applesmc_lock);
533 return 0;
536 /* Reinitialize device on resume from hibernation */
537 static int applesmc_pm_restore(struct device *dev)
539 int ret = applesmc_device_init();
540 if (ret)
541 return ret;
542 return applesmc_pm_resume(dev);
545 static struct dev_pm_ops applesmc_pm_ops = {
546 .resume = applesmc_pm_resume,
547 .restore = applesmc_pm_restore,
550 static struct platform_driver applesmc_driver = {
551 .probe = applesmc_probe,
552 .driver = {
553 .name = "applesmc",
554 .owner = THIS_MODULE,
555 .pm = &applesmc_pm_ops,
560 * applesmc_calibrate - Set our "resting" values. Callers must
561 * hold applesmc_lock.
563 static void applesmc_calibrate(void)
565 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
566 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
567 rest_x = -rest_x;
570 static void applesmc_idev_poll(struct input_polled_dev *dev)
572 struct input_dev *idev = dev->input;
573 s16 x, y;
575 mutex_lock(&applesmc_lock);
577 if (applesmc_read_motion_sensor(SENSOR_X, &x))
578 goto out;
579 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
580 goto out;
582 x = -x;
583 input_report_abs(idev, ABS_X, x - rest_x);
584 input_report_abs(idev, ABS_Y, y - rest_y);
585 input_sync(idev);
587 out:
588 mutex_unlock(&applesmc_lock);
591 /* Sysfs Files */
593 static ssize_t applesmc_name_show(struct device *dev,
594 struct device_attribute *attr, char *buf)
596 return snprintf(buf, PAGE_SIZE, "applesmc\n");
599 static ssize_t applesmc_position_show(struct device *dev,
600 struct device_attribute *attr, char *buf)
602 int ret;
603 s16 x, y, z;
605 mutex_lock(&applesmc_lock);
607 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
608 if (ret)
609 goto out;
610 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
611 if (ret)
612 goto out;
613 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
614 if (ret)
615 goto out;
617 out:
618 mutex_unlock(&applesmc_lock);
619 if (ret)
620 return ret;
621 else
622 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
625 static ssize_t applesmc_light_show(struct device *dev,
626 struct device_attribute *attr, char *sysfsbuf)
628 static int data_length;
629 int ret;
630 u8 left = 0, right = 0;
631 u8 buffer[10], query[6];
633 mutex_lock(&applesmc_lock);
635 if (!data_length) {
636 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
637 if (ret)
638 goto out;
639 data_length = clamp_val(query[0], 0, 10);
640 printk(KERN_INFO "applesmc: light sensor data length set to "
641 "%d\n", data_length);
644 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
645 /* newer macbooks report a single 10-bit bigendian value */
646 if (data_length == 10) {
647 left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2;
648 goto out;
650 left = buffer[2];
651 if (ret)
652 goto out;
653 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
654 right = buffer[2];
656 out:
657 mutex_unlock(&applesmc_lock);
658 if (ret)
659 return ret;
660 else
661 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
664 /* Displays degree Celsius * 1000 */
665 static ssize_t applesmc_show_temperature(struct device *dev,
666 struct device_attribute *devattr, char *sysfsbuf)
668 int ret;
669 u8 buffer[2];
670 unsigned int temp;
671 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
672 const char* key =
673 temperature_sensors_sets[applesmc_temperature_set][attr->index];
675 mutex_lock(&applesmc_lock);
677 ret = applesmc_read_key(key, buffer, 2);
678 temp = buffer[0]*1000;
679 temp += (buffer[1] >> 6) * 250;
681 mutex_unlock(&applesmc_lock);
683 if (ret)
684 return ret;
685 else
686 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
689 static ssize_t applesmc_show_fan_speed(struct device *dev,
690 struct device_attribute *attr, char *sysfsbuf)
692 int ret;
693 unsigned int speed = 0;
694 char newkey[5];
695 u8 buffer[2];
696 struct sensor_device_attribute_2 *sensor_attr =
697 to_sensor_dev_attr_2(attr);
699 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
700 newkey[1] = '0' + sensor_attr->index;
701 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
702 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
703 newkey[4] = 0;
705 mutex_lock(&applesmc_lock);
707 ret = applesmc_read_key(newkey, buffer, 2);
708 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
710 mutex_unlock(&applesmc_lock);
711 if (ret)
712 return ret;
713 else
714 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
717 static ssize_t applesmc_store_fan_speed(struct device *dev,
718 struct device_attribute *attr,
719 const char *sysfsbuf, size_t count)
721 int ret;
722 u32 speed;
723 char newkey[5];
724 u8 buffer[2];
725 struct sensor_device_attribute_2 *sensor_attr =
726 to_sensor_dev_attr_2(attr);
728 speed = simple_strtoul(sysfsbuf, NULL, 10);
730 if (speed > 0x4000) /* Bigger than a 14-bit value */
731 return -EINVAL;
733 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
734 newkey[1] = '0' + sensor_attr->index;
735 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
736 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
737 newkey[4] = 0;
739 mutex_lock(&applesmc_lock);
741 buffer[0] = (speed >> 6) & 0xff;
742 buffer[1] = (speed << 2) & 0xff;
743 ret = applesmc_write_key(newkey, buffer, 2);
745 mutex_unlock(&applesmc_lock);
746 if (ret)
747 return ret;
748 else
749 return count;
752 static ssize_t applesmc_show_fan_manual(struct device *dev,
753 struct device_attribute *devattr, char *sysfsbuf)
755 int ret;
756 u16 manual = 0;
757 u8 buffer[2];
758 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
760 mutex_lock(&applesmc_lock);
762 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
763 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
765 mutex_unlock(&applesmc_lock);
766 if (ret)
767 return ret;
768 else
769 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
772 static ssize_t applesmc_store_fan_manual(struct device *dev,
773 struct device_attribute *devattr,
774 const char *sysfsbuf, size_t count)
776 int ret;
777 u8 buffer[2];
778 u32 input;
779 u16 val;
780 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
782 input = simple_strtoul(sysfsbuf, NULL, 10);
784 mutex_lock(&applesmc_lock);
786 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
787 val = (buffer[0] << 8 | buffer[1]);
788 if (ret)
789 goto out;
791 if (input)
792 val = val | (0x01 << attr->index);
793 else
794 val = val & ~(0x01 << attr->index);
796 buffer[0] = (val >> 8) & 0xFF;
797 buffer[1] = val & 0xFF;
799 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
801 out:
802 mutex_unlock(&applesmc_lock);
803 if (ret)
804 return ret;
805 else
806 return count;
809 static ssize_t applesmc_show_fan_position(struct device *dev,
810 struct device_attribute *attr, char *sysfsbuf)
812 int ret;
813 char newkey[5];
814 u8 buffer[17];
815 struct sensor_device_attribute_2 *sensor_attr =
816 to_sensor_dev_attr_2(attr);
818 newkey[0] = FAN_POSITION[0];
819 newkey[1] = '0' + sensor_attr->index;
820 newkey[2] = FAN_POSITION[2];
821 newkey[3] = FAN_POSITION[3];
822 newkey[4] = 0;
824 mutex_lock(&applesmc_lock);
826 ret = applesmc_read_key(newkey, buffer, 16);
827 buffer[16] = 0;
829 mutex_unlock(&applesmc_lock);
830 if (ret)
831 return ret;
832 else
833 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
836 static ssize_t applesmc_calibrate_show(struct device *dev,
837 struct device_attribute *attr, char *sysfsbuf)
839 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
842 static ssize_t applesmc_calibrate_store(struct device *dev,
843 struct device_attribute *attr, const char *sysfsbuf, size_t count)
845 mutex_lock(&applesmc_lock);
846 applesmc_calibrate();
847 mutex_unlock(&applesmc_lock);
849 return count;
852 static void applesmc_backlight_set(struct work_struct *work)
854 mutex_lock(&applesmc_lock);
855 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
856 mutex_unlock(&applesmc_lock);
858 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
860 static void applesmc_brightness_set(struct led_classdev *led_cdev,
861 enum led_brightness value)
863 int ret;
865 backlight_state[0] = value;
866 ret = queue_work(applesmc_led_wq, &backlight_work);
868 if (debug && (!ret))
869 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
872 static ssize_t applesmc_key_count_show(struct device *dev,
873 struct device_attribute *attr, char *sysfsbuf)
875 int ret;
876 u8 buffer[4];
877 u32 count;
879 mutex_lock(&applesmc_lock);
881 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
882 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
883 ((u32)buffer[2]<<8) + buffer[3];
885 mutex_unlock(&applesmc_lock);
886 if (ret)
887 return ret;
888 else
889 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
892 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
893 struct device_attribute *attr, char *sysfsbuf)
895 char key[5];
896 char info[6];
897 int ret;
899 mutex_lock(&applesmc_lock);
901 ret = applesmc_get_key_at_index(key_at_index, key);
903 if (ret || !key[0]) {
904 mutex_unlock(&applesmc_lock);
906 return -EINVAL;
909 ret = applesmc_get_key_type(key, info);
911 if (ret) {
912 mutex_unlock(&applesmc_lock);
914 return ret;
918 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
919 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
921 ret = applesmc_read_key(key, sysfsbuf, info[0]);
923 mutex_unlock(&applesmc_lock);
925 if (!ret) {
926 return info[0];
927 } else {
928 return ret;
932 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
933 struct device_attribute *attr, char *sysfsbuf)
935 char key[5];
936 char info[6];
937 int ret;
939 mutex_lock(&applesmc_lock);
941 ret = applesmc_get_key_at_index(key_at_index, key);
943 if (ret || !key[0]) {
944 mutex_unlock(&applesmc_lock);
946 return -EINVAL;
949 ret = applesmc_get_key_type(key, info);
951 mutex_unlock(&applesmc_lock);
953 if (!ret)
954 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
955 else
956 return ret;
959 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
960 struct device_attribute *attr, char *sysfsbuf)
962 char key[5];
963 char info[6];
964 int ret;
966 mutex_lock(&applesmc_lock);
968 ret = applesmc_get_key_at_index(key_at_index, key);
970 if (ret || !key[0]) {
971 mutex_unlock(&applesmc_lock);
973 return -EINVAL;
976 ret = applesmc_get_key_type(key, info);
978 mutex_unlock(&applesmc_lock);
980 if (!ret)
981 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
982 else
983 return ret;
986 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
987 struct device_attribute *attr, char *sysfsbuf)
989 char key[5];
990 int ret;
992 mutex_lock(&applesmc_lock);
994 ret = applesmc_get_key_at_index(key_at_index, key);
996 mutex_unlock(&applesmc_lock);
998 if (!ret && key[0])
999 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
1000 else
1001 return -EINVAL;
1004 static ssize_t applesmc_key_at_index_show(struct device *dev,
1005 struct device_attribute *attr, char *sysfsbuf)
1007 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
1010 static ssize_t applesmc_key_at_index_store(struct device *dev,
1011 struct device_attribute *attr, const char *sysfsbuf, size_t count)
1013 mutex_lock(&applesmc_lock);
1015 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
1017 mutex_unlock(&applesmc_lock);
1019 return count;
1022 static struct led_classdev applesmc_backlight = {
1023 .name = "smc::kbd_backlight",
1024 .default_trigger = "nand-disk",
1025 .brightness_set = applesmc_brightness_set,
1028 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
1030 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
1031 static DEVICE_ATTR(calibrate, 0644,
1032 applesmc_calibrate_show, applesmc_calibrate_store);
1034 static struct attribute *accelerometer_attributes[] = {
1035 &dev_attr_position.attr,
1036 &dev_attr_calibrate.attr,
1037 NULL
1040 static const struct attribute_group accelerometer_attributes_group =
1041 { .attrs = accelerometer_attributes };
1043 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
1045 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
1046 static DEVICE_ATTR(key_at_index, 0644,
1047 applesmc_key_at_index_show, applesmc_key_at_index_store);
1048 static DEVICE_ATTR(key_at_index_name, 0444,
1049 applesmc_key_at_index_name_show, NULL);
1050 static DEVICE_ATTR(key_at_index_type, 0444,
1051 applesmc_key_at_index_type_show, NULL);
1052 static DEVICE_ATTR(key_at_index_data_length, 0444,
1053 applesmc_key_at_index_data_length_show, NULL);
1054 static DEVICE_ATTR(key_at_index_data, 0444,
1055 applesmc_key_at_index_read_show, NULL);
1057 static struct attribute *key_enumeration_attributes[] = {
1058 &dev_attr_key_count.attr,
1059 &dev_attr_key_at_index.attr,
1060 &dev_attr_key_at_index_name.attr,
1061 &dev_attr_key_at_index_type.attr,
1062 &dev_attr_key_at_index_data_length.attr,
1063 &dev_attr_key_at_index_data.attr,
1064 NULL
1067 static const struct attribute_group key_enumeration_group =
1068 { .attrs = key_enumeration_attributes };
1071 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1072 * - show actual speed
1073 * - show/store minimum speed
1074 * - show maximum speed
1075 * - show safe speed
1076 * - show/store target speed
1077 * - show/store manual mode
1079 #define sysfs_fan_speeds_offset(offset) \
1080 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1081 applesmc_show_fan_speed, NULL, 0, offset-1); \
1083 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1084 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1086 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1087 applesmc_show_fan_speed, NULL, 2, offset-1); \
1089 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1090 applesmc_show_fan_speed, NULL, 3, offset-1); \
1092 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1093 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1095 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1096 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1098 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1099 applesmc_show_fan_position, NULL, offset-1); \
1101 static struct attribute *fan##offset##_attributes[] = { \
1102 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1103 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1104 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1105 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1106 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1107 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1108 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1109 NULL \
1113 * Create the needed functions for each fan using the macro defined above
1114 * (4 fans are supported)
1116 sysfs_fan_speeds_offset(1);
1117 sysfs_fan_speeds_offset(2);
1118 sysfs_fan_speeds_offset(3);
1119 sysfs_fan_speeds_offset(4);
1121 static const struct attribute_group fan_attribute_groups[] = {
1122 { .attrs = fan1_attributes },
1123 { .attrs = fan2_attributes },
1124 { .attrs = fan3_attributes },
1125 { .attrs = fan4_attributes },
1129 * Temperature sensors sysfs entries.
1131 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1132 applesmc_show_temperature, NULL, 0);
1133 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1134 applesmc_show_temperature, NULL, 1);
1135 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1136 applesmc_show_temperature, NULL, 2);
1137 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1138 applesmc_show_temperature, NULL, 3);
1139 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1140 applesmc_show_temperature, NULL, 4);
1141 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1142 applesmc_show_temperature, NULL, 5);
1143 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1144 applesmc_show_temperature, NULL, 6);
1145 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1146 applesmc_show_temperature, NULL, 7);
1147 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1148 applesmc_show_temperature, NULL, 8);
1149 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1150 applesmc_show_temperature, NULL, 9);
1151 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1152 applesmc_show_temperature, NULL, 10);
1153 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1154 applesmc_show_temperature, NULL, 11);
1155 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1156 applesmc_show_temperature, NULL, 12);
1157 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1158 applesmc_show_temperature, NULL, 13);
1159 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1160 applesmc_show_temperature, NULL, 14);
1161 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1162 applesmc_show_temperature, NULL, 15);
1163 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1164 applesmc_show_temperature, NULL, 16);
1165 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1166 applesmc_show_temperature, NULL, 17);
1167 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1168 applesmc_show_temperature, NULL, 18);
1169 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1170 applesmc_show_temperature, NULL, 19);
1171 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1172 applesmc_show_temperature, NULL, 20);
1173 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1174 applesmc_show_temperature, NULL, 21);
1175 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1176 applesmc_show_temperature, NULL, 22);
1177 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1178 applesmc_show_temperature, NULL, 23);
1179 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1180 applesmc_show_temperature, NULL, 24);
1181 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1182 applesmc_show_temperature, NULL, 25);
1183 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1184 applesmc_show_temperature, NULL, 26);
1185 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1186 applesmc_show_temperature, NULL, 27);
1187 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1188 applesmc_show_temperature, NULL, 28);
1189 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1190 applesmc_show_temperature, NULL, 29);
1191 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1192 applesmc_show_temperature, NULL, 30);
1193 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1194 applesmc_show_temperature, NULL, 31);
1195 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1196 applesmc_show_temperature, NULL, 32);
1197 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1198 applesmc_show_temperature, NULL, 33);
1199 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1200 applesmc_show_temperature, NULL, 34);
1201 static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
1202 applesmc_show_temperature, NULL, 35);
1203 static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
1204 applesmc_show_temperature, NULL, 36);
1205 static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
1206 applesmc_show_temperature, NULL, 37);
1207 static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
1208 applesmc_show_temperature, NULL, 38);
1209 static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
1210 applesmc_show_temperature, NULL, 39);
1212 static struct attribute *temperature_attributes[] = {
1213 &sensor_dev_attr_temp1_input.dev_attr.attr,
1214 &sensor_dev_attr_temp2_input.dev_attr.attr,
1215 &sensor_dev_attr_temp3_input.dev_attr.attr,
1216 &sensor_dev_attr_temp4_input.dev_attr.attr,
1217 &sensor_dev_attr_temp5_input.dev_attr.attr,
1218 &sensor_dev_attr_temp6_input.dev_attr.attr,
1219 &sensor_dev_attr_temp7_input.dev_attr.attr,
1220 &sensor_dev_attr_temp8_input.dev_attr.attr,
1221 &sensor_dev_attr_temp9_input.dev_attr.attr,
1222 &sensor_dev_attr_temp10_input.dev_attr.attr,
1223 &sensor_dev_attr_temp11_input.dev_attr.attr,
1224 &sensor_dev_attr_temp12_input.dev_attr.attr,
1225 &sensor_dev_attr_temp13_input.dev_attr.attr,
1226 &sensor_dev_attr_temp14_input.dev_attr.attr,
1227 &sensor_dev_attr_temp15_input.dev_attr.attr,
1228 &sensor_dev_attr_temp16_input.dev_attr.attr,
1229 &sensor_dev_attr_temp17_input.dev_attr.attr,
1230 &sensor_dev_attr_temp18_input.dev_attr.attr,
1231 &sensor_dev_attr_temp19_input.dev_attr.attr,
1232 &sensor_dev_attr_temp20_input.dev_attr.attr,
1233 &sensor_dev_attr_temp21_input.dev_attr.attr,
1234 &sensor_dev_attr_temp22_input.dev_attr.attr,
1235 &sensor_dev_attr_temp23_input.dev_attr.attr,
1236 &sensor_dev_attr_temp24_input.dev_attr.attr,
1237 &sensor_dev_attr_temp25_input.dev_attr.attr,
1238 &sensor_dev_attr_temp26_input.dev_attr.attr,
1239 &sensor_dev_attr_temp27_input.dev_attr.attr,
1240 &sensor_dev_attr_temp28_input.dev_attr.attr,
1241 &sensor_dev_attr_temp29_input.dev_attr.attr,
1242 &sensor_dev_attr_temp30_input.dev_attr.attr,
1243 &sensor_dev_attr_temp31_input.dev_attr.attr,
1244 &sensor_dev_attr_temp32_input.dev_attr.attr,
1245 &sensor_dev_attr_temp33_input.dev_attr.attr,
1246 &sensor_dev_attr_temp34_input.dev_attr.attr,
1247 &sensor_dev_attr_temp35_input.dev_attr.attr,
1248 &sensor_dev_attr_temp36_input.dev_attr.attr,
1249 &sensor_dev_attr_temp37_input.dev_attr.attr,
1250 &sensor_dev_attr_temp38_input.dev_attr.attr,
1251 &sensor_dev_attr_temp39_input.dev_attr.attr,
1252 &sensor_dev_attr_temp40_input.dev_attr.attr,
1253 NULL
1256 static const struct attribute_group temperature_attributes_group =
1257 { .attrs = temperature_attributes };
1259 /* Module stuff */
1262 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1264 static int applesmc_dmi_match(const struct dmi_system_id *id)
1266 int i = 0;
1267 struct dmi_match_data* dmi_data = id->driver_data;
1268 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1269 applesmc_accelerometer = dmi_data->accelerometer;
1270 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1271 applesmc_accelerometer ? "with" : "without");
1272 applesmc_light = dmi_data->light;
1273 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1274 applesmc_light ? "with" : "without");
1276 applesmc_temperature_set = dmi_data->temperature_set;
1277 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1278 i++;
1279 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1280 return 1;
1283 /* Create accelerometer ressources */
1284 static int applesmc_create_accelerometer(void)
1286 struct input_dev *idev;
1287 int ret;
1289 ret = sysfs_create_group(&pdev->dev.kobj,
1290 &accelerometer_attributes_group);
1291 if (ret)
1292 goto out;
1294 applesmc_idev = input_allocate_polled_device();
1295 if (!applesmc_idev) {
1296 ret = -ENOMEM;
1297 goto out_sysfs;
1300 applesmc_idev->poll = applesmc_idev_poll;
1301 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1303 /* initial calibrate for the input device */
1304 applesmc_calibrate();
1306 /* initialize the input device */
1307 idev = applesmc_idev->input;
1308 idev->name = "applesmc";
1309 idev->id.bustype = BUS_HOST;
1310 idev->dev.parent = &pdev->dev;
1311 idev->evbit[0] = BIT_MASK(EV_ABS);
1312 input_set_abs_params(idev, ABS_X,
1313 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1314 input_set_abs_params(idev, ABS_Y,
1315 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1317 ret = input_register_polled_device(applesmc_idev);
1318 if (ret)
1319 goto out_idev;
1321 return 0;
1323 out_idev:
1324 input_free_polled_device(applesmc_idev);
1326 out_sysfs:
1327 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1329 out:
1330 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1331 return ret;
1334 /* Release all ressources used by the accelerometer */
1335 static void applesmc_release_accelerometer(void)
1337 input_unregister_polled_device(applesmc_idev);
1338 input_free_polled_device(applesmc_idev);
1339 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1342 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1343 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1344 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1345 /* MacBook2: accelerometer and temperature set 1 */
1346 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1347 /* MacBook: accelerometer and temperature set 2 */
1348 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1349 /* MacMini: temperature set 3 */
1350 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1351 /* MacPro: temperature set 4 */
1352 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1353 /* iMac: temperature set 5 */
1354 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1355 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1356 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1357 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1358 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1359 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1360 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1361 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1362 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1363 /* iMac 5: light sensor only, temperature set 10 */
1364 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1365 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1366 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
1367 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1368 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
1369 /* iMac 8: light sensor only, temperature set 13 */
1370 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
1371 /* iMac 6: light sensor only, temperature set 14 */
1372 { .accelerometer = 0, .light = 0, .temperature_set = 14 },
1373 /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
1374 { .accelerometer = 1, .light = 1, .temperature_set = 15 },
1375 /* MacPro3,1: temperature set 16 */
1376 { .accelerometer = 0, .light = 0, .temperature_set = 16 },
1377 /* iMac 9,1: light sensor only, temperature set 17 */
1378 { .accelerometer = 0, .light = 0, .temperature_set = 17 },
1379 /* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
1380 { .accelerometer = 1, .light = 1, .temperature_set = 18 },
1381 /* MacBook Pro 5,3: accelerometer, backlight and temperature set 19 */
1382 { .accelerometer = 1, .light = 1, .temperature_set = 19 },
1383 /* MacBook Pro 5,4: accelerometer, backlight and temperature set 20 */
1384 { .accelerometer = 1, .light = 1, .temperature_set = 20 },
1385 /* MacBook Pro 6,2: accelerometer, backlight and temperature set 21 */
1386 { .accelerometer = 1, .light = 1, .temperature_set = 21 },
1387 /* MacBook Pro 7,1: accelerometer, backlight and temperature set 22 */
1388 { .accelerometer = 1, .light = 1, .temperature_set = 22 },
1389 /* MacBook Air 3,1: accelerometer, backlight and temperature set 23 */
1390 { .accelerometer = 0, .light = 0, .temperature_set = 23 },
1393 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1394 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1395 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1396 { applesmc_dmi_match, "Apple MacBook Air 3", {
1397 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1398 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3") },
1399 &applesmc_dmi_data[23]},
1400 { applesmc_dmi_match, "Apple MacBook Air 2", {
1401 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1402 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
1403 &applesmc_dmi_data[15]},
1404 { applesmc_dmi_match, "Apple MacBook Air", {
1405 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1406 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1407 &applesmc_dmi_data[7]},
1408 { applesmc_dmi_match, "Apple MacBook Pro 7", {
1409 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1410 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro7") },
1411 &applesmc_dmi_data[22]},
1412 { applesmc_dmi_match, "Apple MacBook Pro 5,4", {
1413 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1414 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4") },
1415 &applesmc_dmi_data[20]},
1416 { applesmc_dmi_match, "Apple MacBook Pro 5,3", {
1417 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1418 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3") },
1419 &applesmc_dmi_data[19]},
1420 { applesmc_dmi_match, "Apple MacBook Pro 6", {
1421 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1422 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6") },
1423 &applesmc_dmi_data[21]},
1424 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1425 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1426 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1427 &applesmc_dmi_data[12]},
1428 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1429 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1430 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1431 &applesmc_dmi_data[8]},
1432 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1433 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1434 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1435 &applesmc_dmi_data[9]},
1436 { applesmc_dmi_match, "Apple MacBook Pro 2,2", {
1437 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
1438 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
1439 &applesmc_dmi_data[18]},
1440 { applesmc_dmi_match, "Apple MacBook Pro", {
1441 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1442 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1443 &applesmc_dmi_data[0]},
1444 { applesmc_dmi_match, "Apple MacBook (v2)", {
1445 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1446 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1447 &applesmc_dmi_data[1]},
1448 { applesmc_dmi_match, "Apple MacBook (v3)", {
1449 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1450 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1451 &applesmc_dmi_data[6]},
1452 { applesmc_dmi_match, "Apple MacBook 4", {
1453 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1454 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1455 &applesmc_dmi_data[6]},
1456 { applesmc_dmi_match, "Apple MacBook 5", {
1457 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1458 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1459 &applesmc_dmi_data[11]},
1460 { applesmc_dmi_match, "Apple MacBook", {
1461 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1462 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1463 &applesmc_dmi_data[2]},
1464 { applesmc_dmi_match, "Apple Macmini", {
1465 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1466 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1467 &applesmc_dmi_data[3]},
1468 { applesmc_dmi_match, "Apple MacPro2", {
1469 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1470 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1471 &applesmc_dmi_data[4]},
1472 { applesmc_dmi_match, "Apple MacPro3", {
1473 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1474 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") },
1475 &applesmc_dmi_data[16]},
1476 { applesmc_dmi_match, "Apple MacPro", {
1477 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1478 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1479 &applesmc_dmi_data[4]},
1480 { applesmc_dmi_match, "Apple iMac 9,1", {
1481 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
1482 DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
1483 &applesmc_dmi_data[17]},
1484 { applesmc_dmi_match, "Apple iMac 8", {
1485 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1486 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1487 &applesmc_dmi_data[13]},
1488 { applesmc_dmi_match, "Apple iMac 6", {
1489 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1490 DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
1491 &applesmc_dmi_data[14]},
1492 { applesmc_dmi_match, "Apple iMac 5", {
1493 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1494 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1495 &applesmc_dmi_data[10]},
1496 { applesmc_dmi_match, "Apple iMac", {
1497 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1498 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1499 &applesmc_dmi_data[5]},
1500 { .ident = NULL }
1503 static int __init applesmc_init(void)
1505 int ret;
1506 int count;
1507 int i;
1509 if (!dmi_check_system(applesmc_whitelist)) {
1510 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1511 ret = -ENODEV;
1512 goto out;
1515 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1516 "applesmc")) {
1517 ret = -ENXIO;
1518 goto out;
1521 ret = platform_driver_register(&applesmc_driver);
1522 if (ret)
1523 goto out_region;
1525 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1526 NULL, 0);
1527 if (IS_ERR(pdev)) {
1528 ret = PTR_ERR(pdev);
1529 goto out_driver;
1532 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1533 if (ret)
1534 goto out_device;
1536 /* Create key enumeration sysfs files */
1537 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1538 if (ret)
1539 goto out_name;
1541 /* create fan files */
1542 count = applesmc_get_fan_count();
1543 if (count < 0) {
1544 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1545 } else {
1546 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1548 switch (count) {
1549 default:
1550 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1551 " but at most 4 fans are supported"
1552 " by the driver.\n");
1553 case 4:
1554 ret = sysfs_create_group(&pdev->dev.kobj,
1555 &fan_attribute_groups[3]);
1556 if (ret)
1557 goto out_key_enumeration;
1558 case 3:
1559 ret = sysfs_create_group(&pdev->dev.kobj,
1560 &fan_attribute_groups[2]);
1561 if (ret)
1562 goto out_key_enumeration;
1563 case 2:
1564 ret = sysfs_create_group(&pdev->dev.kobj,
1565 &fan_attribute_groups[1]);
1566 if (ret)
1567 goto out_key_enumeration;
1568 case 1:
1569 ret = sysfs_create_group(&pdev->dev.kobj,
1570 &fan_attribute_groups[0]);
1571 if (ret)
1572 goto out_fan_1;
1573 case 0:
1578 for (i = 0;
1579 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1580 i++) {
1581 if (temperature_attributes[i] == NULL) {
1582 printk(KERN_ERR "applesmc: More temperature sensors "
1583 "in temperature_sensors_sets (at least %i)"
1584 "than available sysfs files in "
1585 "temperature_attributes (%i), please report "
1586 "this bug.\n", i, i-1);
1587 goto out_temperature;
1589 ret = sysfs_create_file(&pdev->dev.kobj,
1590 temperature_attributes[i]);
1591 if (ret)
1592 goto out_temperature;
1595 if (applesmc_accelerometer) {
1596 ret = applesmc_create_accelerometer();
1597 if (ret)
1598 goto out_temperature;
1601 if (applesmc_light) {
1602 /* Add light sensor file */
1603 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1604 if (ret)
1605 goto out_accelerometer;
1607 /* Create the workqueue */
1608 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1609 if (!applesmc_led_wq) {
1610 ret = -ENOMEM;
1611 goto out_light_sysfs;
1614 /* register as a led device */
1615 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1616 if (ret < 0)
1617 goto out_light_wq;
1620 hwmon_dev = hwmon_device_register(&pdev->dev);
1621 if (IS_ERR(hwmon_dev)) {
1622 ret = PTR_ERR(hwmon_dev);
1623 goto out_light_ledclass;
1626 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1628 return 0;
1630 out_light_ledclass:
1631 if (applesmc_light)
1632 led_classdev_unregister(&applesmc_backlight);
1633 out_light_wq:
1634 if (applesmc_light)
1635 destroy_workqueue(applesmc_led_wq);
1636 out_light_sysfs:
1637 if (applesmc_light)
1638 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1639 out_accelerometer:
1640 if (applesmc_accelerometer)
1641 applesmc_release_accelerometer();
1642 out_temperature:
1643 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1644 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1645 out_fan_1:
1646 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1647 out_key_enumeration:
1648 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1649 out_name:
1650 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1651 out_device:
1652 platform_device_unregister(pdev);
1653 out_driver:
1654 platform_driver_unregister(&applesmc_driver);
1655 out_region:
1656 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1657 out:
1658 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1659 return ret;
1662 static void __exit applesmc_exit(void)
1664 hwmon_device_unregister(hwmon_dev);
1665 if (applesmc_light) {
1666 led_classdev_unregister(&applesmc_backlight);
1667 destroy_workqueue(applesmc_led_wq);
1668 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1670 if (applesmc_accelerometer)
1671 applesmc_release_accelerometer();
1672 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1673 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1674 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1675 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1676 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1677 platform_device_unregister(pdev);
1678 platform_driver_unregister(&applesmc_driver);
1679 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1681 printk(KERN_INFO "applesmc: driver unloaded.\n");
1684 module_init(applesmc_init);
1685 module_exit(applesmc_exit);
1687 MODULE_AUTHOR("Nicolas Boichat");
1688 MODULE_DESCRIPTION("Apple SMC");
1689 MODULE_LICENSE("GPL v2");
1690 MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);