2 * drivers/hwmon/applesmc.c - driver for Apple's SMC (accelerometer, temperature
3 * sensors, fan control, keyboard backlight control) used in Intel-based Apple
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
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>
39 #include <linux/leds.h>
40 #include <linux/hwmon.h>
41 #include <linux/workqueue.h>
43 /* data port used by Apple SMC */
44 #define APPLESMC_DATA_PORT 0x300
45 /* command/status port used by Apple SMC */
46 #define APPLESMC_CMD_PORT 0x304
48 #define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
50 #define APPLESMC_MAX_DATA_LENGTH 32
52 #define APPLESMC_MIN_WAIT 0x0040
53 #define APPLESMC_MAX_WAIT 0x8000
55 #define APPLESMC_STATUS_MASK 0x0f
56 #define APPLESMC_READ_CMD 0x10
57 #define APPLESMC_WRITE_CMD 0x11
58 #define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12
59 #define APPLESMC_GET_KEY_TYPE_CMD 0x13
61 #define KEY_COUNT_KEY "#KEY" /* r-o ui32 */
63 #define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6-10 bytes) */
64 #define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6-10 bytes) */
65 #define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */
67 #define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */
69 #define MOTION_SENSOR_X_KEY "MO_X" /* r-o sp78 (2 bytes) */
70 #define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o sp78 (2 bytes) */
71 #define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o sp78 (2 bytes) */
72 #define MOTION_SENSOR_KEY "MOCN" /* r/w ui16 */
74 #define FANS_COUNT "FNum" /* r-o ui8 */
75 #define FANS_MANUAL "FS! " /* r-w ui16 */
76 #define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */
77 #define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 (2 bytes) */
78 #define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 (2 bytes) */
79 #define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 (2 bytes) */
80 #define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */
81 #define FAN_POSITION "F0ID" /* r-o char[16] */
84 * Temperature sensors keys (sp78 - 2 bytes).
86 static const char* temperature_sensors_sets[][36] = {
87 /* Set 0: Macbook Pro */
88 { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
89 "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
90 /* Set 1: Macbook2 set */
91 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "TTF0", "Th0H",
92 "Th0S", "Th1H", NULL },
93 /* Set 2: Macbook set */
94 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S",
95 "Th1H", "Ts0P", NULL },
96 /* Set 3: Macmini set */
97 { "TC0D", "TC0P", NULL },
98 /* Set 4: Mac Pro (2 x Quad-Core) */
99 { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
100 "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P",
101 "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S",
102 "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P",
103 "TM9S", "TN0H", "TS0C", NULL },
105 { "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P",
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",
140 /* List of keys used to read/write fan speeds */
141 static const char* fan_speed_keys[] = {
149 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
150 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
152 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
153 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
154 #define APPLESMC_INPUT_FLAT 4
160 /* Structure to be passed to DMI_MATCH function */
161 struct dmi_match_data {
162 /* Indicates whether this computer has an accelerometer. */
164 /* Indicates whether this computer has light sensors and keyboard backlight. */
166 /* Indicates which temperature sensors set to use. */
170 static const int debug;
171 static struct platform_device *pdev;
174 static struct device *hwmon_dev;
175 static struct input_polled_dev *applesmc_idev;
177 /* Indicates whether this computer has an accelerometer. */
178 static unsigned int applesmc_accelerometer;
180 /* Indicates whether this computer has light sensors and keyboard backlight. */
181 static unsigned int applesmc_light;
183 /* Indicates which temperature sensors set to use. */
184 static unsigned int applesmc_temperature_set;
186 static DEFINE_MUTEX(applesmc_lock);
189 * Last index written to key_at_index sysfs file, and value to use for all other
190 * key_at_index_* sysfs files.
192 static unsigned int key_at_index;
194 static struct workqueue_struct *applesmc_led_wq;
197 * __wait_status - Wait up to 32ms for the status port to get a certain value
198 * (masked with 0x0f), returning zero if the value is obtained. Callers must
199 * hold applesmc_lock.
201 static int __wait_status(u8 val)
205 val = val & APPLESMC_STATUS_MASK;
207 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
209 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
212 "Waited %d us for status %x\n",
213 2 * us - APPLESMC_MIN_WAIT, val);
218 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
219 val, inb(APPLESMC_CMD_PORT));
225 * special treatment of command port - on newer macbooks, it seems necessary
226 * to resend the command byte before polling the status again. Callers must
227 * hold applesmc_lock.
229 static int send_command(u8 cmd)
232 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
233 outb(cmd, APPLESMC_CMD_PORT);
235 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
238 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
239 cmd, inb(APPLESMC_CMD_PORT));
244 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
245 * Returns zero on success or a negative error on failure. Callers must
246 * hold applesmc_lock.
248 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
252 if (len > APPLESMC_MAX_DATA_LENGTH) {
253 printk(KERN_ERR "applesmc_read_key: cannot read more than "
254 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
258 if (send_command(APPLESMC_READ_CMD))
261 for (i = 0; i < 4; i++) {
262 outb(key[i], APPLESMC_DATA_PORT);
263 if (__wait_status(0x04))
267 printk(KERN_DEBUG "<%s", key);
269 outb(len, APPLESMC_DATA_PORT);
271 printk(KERN_DEBUG ">%x", len);
273 for (i = 0; i < len; i++) {
274 if (__wait_status(0x05))
276 buffer[i] = inb(APPLESMC_DATA_PORT);
278 printk(KERN_DEBUG "<%x", buffer[i]);
281 printk(KERN_DEBUG "\n");
287 * applesmc_write_key - writes len bytes from buffer to a given key.
288 * Returns zero on success or a negative error on failure. Callers must
289 * hold applesmc_lock.
291 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
295 if (len > APPLESMC_MAX_DATA_LENGTH) {
296 printk(KERN_ERR "applesmc_write_key: cannot write more than "
297 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
301 if (send_command(APPLESMC_WRITE_CMD))
304 for (i = 0; i < 4; i++) {
305 outb(key[i], APPLESMC_DATA_PORT);
306 if (__wait_status(0x04))
310 outb(len, APPLESMC_DATA_PORT);
312 for (i = 0; i < len; i++) {
313 if (__wait_status(0x04))
315 outb(buffer[i], APPLESMC_DATA_PORT);
322 * applesmc_get_key_at_index - get key at index, and put the result in key
323 * (char[6]). Returns zero on success or a negative error on failure. Callers
324 * must hold applesmc_lock.
326 static int applesmc_get_key_at_index(int index, char* key)
330 readkey[0] = index >> 24;
331 readkey[1] = index >> 16;
332 readkey[2] = index >> 8;
335 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
338 for (i = 0; i < 4; i++) {
339 outb(readkey[i], APPLESMC_DATA_PORT);
340 if (__wait_status(0x04))
344 outb(4, APPLESMC_DATA_PORT);
346 for (i = 0; i < 4; i++) {
347 if (__wait_status(0x05))
349 key[i] = inb(APPLESMC_DATA_PORT);
357 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
358 * Returns zero on success or a negative error on failure. Callers must
359 * hold applesmc_lock.
361 static int applesmc_get_key_type(char* key, char* type)
365 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
368 for (i = 0; i < 4; i++) {
369 outb(key[i], APPLESMC_DATA_PORT);
370 if (__wait_status(0x04))
374 outb(6, APPLESMC_DATA_PORT);
376 for (i = 0; i < 6; i++) {
377 if (__wait_status(0x05))
379 type[i] = inb(APPLESMC_DATA_PORT);
387 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
388 * hold applesmc_lock.
390 static int applesmc_read_motion_sensor(int index, s16* value)
397 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
400 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
403 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
409 *value = ((s16)buffer[0] << 8) | buffer[1];
415 * applesmc_device_init - initialize the accelerometer. Returns zero on success
416 * and negative error code on failure. Can sleep.
418 static int applesmc_device_init(void)
420 int total, ret = -ENXIO;
423 if (!applesmc_accelerometer)
426 mutex_lock(&applesmc_lock);
428 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
430 printk(KERN_DEBUG "applesmc try %d\n", total);
431 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
432 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
433 if (total == INIT_TIMEOUT_MSECS) {
434 printk(KERN_DEBUG "applesmc: device has"
435 " already been initialized"
436 " (0x%02x, 0x%02x).\n",
437 buffer[0], buffer[1]);
439 printk(KERN_DEBUG "applesmc: device"
440 " successfully initialized"
441 " (0x%02x, 0x%02x).\n",
442 buffer[0], buffer[1]);
449 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
450 msleep(INIT_WAIT_MSECS);
453 printk(KERN_WARNING "applesmc: failed to init the device\n");
456 mutex_unlock(&applesmc_lock);
461 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
464 static int applesmc_get_fan_count(void)
469 mutex_lock(&applesmc_lock);
471 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
473 mutex_unlock(&applesmc_lock);
480 /* Device model stuff */
481 static int applesmc_probe(struct platform_device *dev)
485 ret = applesmc_device_init();
489 printk(KERN_INFO "applesmc: device successfully initialized.\n");
493 static int applesmc_resume(struct platform_device *dev)
495 return applesmc_device_init();
498 static struct platform_driver applesmc_driver = {
499 .probe = applesmc_probe,
500 .resume = applesmc_resume,
503 .owner = THIS_MODULE,
508 * applesmc_calibrate - Set our "resting" values. Callers must
509 * hold applesmc_lock.
511 static void applesmc_calibrate(void)
513 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
514 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
518 static void applesmc_idev_poll(struct input_polled_dev *dev)
520 struct input_dev *idev = dev->input;
523 mutex_lock(&applesmc_lock);
525 if (applesmc_read_motion_sensor(SENSOR_X, &x))
527 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
531 input_report_abs(idev, ABS_X, x - rest_x);
532 input_report_abs(idev, ABS_Y, y - rest_y);
536 mutex_unlock(&applesmc_lock);
541 static ssize_t applesmc_name_show(struct device *dev,
542 struct device_attribute *attr, char *buf)
544 return snprintf(buf, PAGE_SIZE, "applesmc\n");
547 static ssize_t applesmc_position_show(struct device *dev,
548 struct device_attribute *attr, char *buf)
553 mutex_lock(&applesmc_lock);
555 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
558 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
561 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
566 mutex_unlock(&applesmc_lock);
570 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
573 static ssize_t applesmc_light_show(struct device *dev,
574 struct device_attribute *attr, char *sysfsbuf)
576 static int data_length;
578 u8 left = 0, right = 0;
579 u8 buffer[10], query[6];
581 mutex_lock(&applesmc_lock);
584 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
587 data_length = clamp_val(query[0], 0, 10);
588 printk(KERN_INFO "applesmc: light sensor data length set to "
589 "%d\n", data_length);
592 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
596 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
600 mutex_unlock(&applesmc_lock);
604 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
607 /* Displays degree Celsius * 1000 */
608 static ssize_t applesmc_show_temperature(struct device *dev,
609 struct device_attribute *devattr, char *sysfsbuf)
614 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
616 temperature_sensors_sets[applesmc_temperature_set][attr->index];
618 mutex_lock(&applesmc_lock);
620 ret = applesmc_read_key(key, buffer, 2);
621 temp = buffer[0]*1000;
622 temp += (buffer[1] >> 6) * 250;
624 mutex_unlock(&applesmc_lock);
629 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
632 static ssize_t applesmc_show_fan_speed(struct device *dev,
633 struct device_attribute *attr, char *sysfsbuf)
636 unsigned int speed = 0;
639 struct sensor_device_attribute_2 *sensor_attr =
640 to_sensor_dev_attr_2(attr);
642 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
643 newkey[1] = '0' + sensor_attr->index;
644 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
645 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
648 mutex_lock(&applesmc_lock);
650 ret = applesmc_read_key(newkey, buffer, 2);
651 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
653 mutex_unlock(&applesmc_lock);
657 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
660 static ssize_t applesmc_store_fan_speed(struct device *dev,
661 struct device_attribute *attr,
662 const char *sysfsbuf, size_t count)
668 struct sensor_device_attribute_2 *sensor_attr =
669 to_sensor_dev_attr_2(attr);
671 speed = simple_strtoul(sysfsbuf, NULL, 10);
673 if (speed > 0x4000) /* Bigger than a 14-bit value */
676 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
677 newkey[1] = '0' + sensor_attr->index;
678 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
679 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
682 mutex_lock(&applesmc_lock);
684 buffer[0] = (speed >> 6) & 0xff;
685 buffer[1] = (speed << 2) & 0xff;
686 ret = applesmc_write_key(newkey, buffer, 2);
688 mutex_unlock(&applesmc_lock);
695 static ssize_t applesmc_show_fan_manual(struct device *dev,
696 struct device_attribute *devattr, char *sysfsbuf)
701 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
703 mutex_lock(&applesmc_lock);
705 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
706 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
708 mutex_unlock(&applesmc_lock);
712 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
715 static ssize_t applesmc_store_fan_manual(struct device *dev,
716 struct device_attribute *devattr,
717 const char *sysfsbuf, size_t count)
723 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
725 input = simple_strtoul(sysfsbuf, NULL, 10);
727 mutex_lock(&applesmc_lock);
729 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
730 val = (buffer[0] << 8 | buffer[1]);
735 val = val | (0x01 << attr->index);
737 val = val & ~(0x01 << attr->index);
739 buffer[0] = (val >> 8) & 0xFF;
740 buffer[1] = val & 0xFF;
742 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
745 mutex_unlock(&applesmc_lock);
752 static ssize_t applesmc_show_fan_position(struct device *dev,
753 struct device_attribute *attr, char *sysfsbuf)
758 struct sensor_device_attribute_2 *sensor_attr =
759 to_sensor_dev_attr_2(attr);
761 newkey[0] = FAN_POSITION[0];
762 newkey[1] = '0' + sensor_attr->index;
763 newkey[2] = FAN_POSITION[2];
764 newkey[3] = FAN_POSITION[3];
767 mutex_lock(&applesmc_lock);
769 ret = applesmc_read_key(newkey, buffer, 16);
772 mutex_unlock(&applesmc_lock);
776 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
779 static ssize_t applesmc_calibrate_show(struct device *dev,
780 struct device_attribute *attr, char *sysfsbuf)
782 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
785 static ssize_t applesmc_calibrate_store(struct device *dev,
786 struct device_attribute *attr, const char *sysfsbuf, size_t count)
788 mutex_lock(&applesmc_lock);
789 applesmc_calibrate();
790 mutex_unlock(&applesmc_lock);
795 /* Store the next backlight value to be written by the work */
796 static unsigned int backlight_value;
798 static void applesmc_backlight_set(struct work_struct *work)
802 mutex_lock(&applesmc_lock);
803 buffer[0] = backlight_value;
805 applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
806 mutex_unlock(&applesmc_lock);
808 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
810 static void applesmc_brightness_set(struct led_classdev *led_cdev,
811 enum led_brightness value)
815 backlight_value = value;
816 ret = queue_work(applesmc_led_wq, &backlight_work);
819 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
822 static ssize_t applesmc_key_count_show(struct device *dev,
823 struct device_attribute *attr, char *sysfsbuf)
829 mutex_lock(&applesmc_lock);
831 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
832 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
833 ((u32)buffer[2]<<8) + buffer[3];
835 mutex_unlock(&applesmc_lock);
839 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
842 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
843 struct device_attribute *attr, char *sysfsbuf)
849 mutex_lock(&applesmc_lock);
851 ret = applesmc_get_key_at_index(key_at_index, key);
853 if (ret || !key[0]) {
854 mutex_unlock(&applesmc_lock);
859 ret = applesmc_get_key_type(key, info);
862 mutex_unlock(&applesmc_lock);
868 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
869 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
871 ret = applesmc_read_key(key, sysfsbuf, info[0]);
873 mutex_unlock(&applesmc_lock);
882 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
883 struct device_attribute *attr, char *sysfsbuf)
889 mutex_lock(&applesmc_lock);
891 ret = applesmc_get_key_at_index(key_at_index, key);
893 if (ret || !key[0]) {
894 mutex_unlock(&applesmc_lock);
899 ret = applesmc_get_key_type(key, info);
901 mutex_unlock(&applesmc_lock);
904 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
909 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
910 struct device_attribute *attr, char *sysfsbuf)
916 mutex_lock(&applesmc_lock);
918 ret = applesmc_get_key_at_index(key_at_index, key);
920 if (ret || !key[0]) {
921 mutex_unlock(&applesmc_lock);
926 ret = applesmc_get_key_type(key, info);
928 mutex_unlock(&applesmc_lock);
931 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
936 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
937 struct device_attribute *attr, char *sysfsbuf)
942 mutex_lock(&applesmc_lock);
944 ret = applesmc_get_key_at_index(key_at_index, key);
946 mutex_unlock(&applesmc_lock);
949 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
954 static ssize_t applesmc_key_at_index_show(struct device *dev,
955 struct device_attribute *attr, char *sysfsbuf)
957 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
960 static ssize_t applesmc_key_at_index_store(struct device *dev,
961 struct device_attribute *attr, const char *sysfsbuf, size_t count)
963 mutex_lock(&applesmc_lock);
965 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
967 mutex_unlock(&applesmc_lock);
972 static struct led_classdev applesmc_backlight = {
973 .name = "smc::kbd_backlight",
974 .default_trigger = "nand-disk",
975 .brightness_set = applesmc_brightness_set,
978 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
980 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
981 static DEVICE_ATTR(calibrate, 0644,
982 applesmc_calibrate_show, applesmc_calibrate_store);
984 static struct attribute *accelerometer_attributes[] = {
985 &dev_attr_position.attr,
986 &dev_attr_calibrate.attr,
990 static const struct attribute_group accelerometer_attributes_group =
991 { .attrs = accelerometer_attributes };
993 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
995 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
996 static DEVICE_ATTR(key_at_index, 0644,
997 applesmc_key_at_index_show, applesmc_key_at_index_store);
998 static DEVICE_ATTR(key_at_index_name, 0444,
999 applesmc_key_at_index_name_show, NULL);
1000 static DEVICE_ATTR(key_at_index_type, 0444,
1001 applesmc_key_at_index_type_show, NULL);
1002 static DEVICE_ATTR(key_at_index_data_length, 0444,
1003 applesmc_key_at_index_data_length_show, NULL);
1004 static DEVICE_ATTR(key_at_index_data, 0444,
1005 applesmc_key_at_index_read_show, NULL);
1007 static struct attribute *key_enumeration_attributes[] = {
1008 &dev_attr_key_count.attr,
1009 &dev_attr_key_at_index.attr,
1010 &dev_attr_key_at_index_name.attr,
1011 &dev_attr_key_at_index_type.attr,
1012 &dev_attr_key_at_index_data_length.attr,
1013 &dev_attr_key_at_index_data.attr,
1017 static const struct attribute_group key_enumeration_group =
1018 { .attrs = key_enumeration_attributes };
1021 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1022 * - show actual speed
1023 * - show/store minimum speed
1024 * - show maximum speed
1026 * - show/store target speed
1027 * - show/store manual mode
1029 #define sysfs_fan_speeds_offset(offset) \
1030 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1031 applesmc_show_fan_speed, NULL, 0, offset-1); \
1033 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1034 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1036 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1037 applesmc_show_fan_speed, NULL, 2, offset-1); \
1039 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1040 applesmc_show_fan_speed, NULL, 3, offset-1); \
1042 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1043 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1045 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1046 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1048 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1049 applesmc_show_fan_position, NULL, offset-1); \
1051 static struct attribute *fan##offset##_attributes[] = { \
1052 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1053 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1054 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1055 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1056 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1057 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1058 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1063 * Create the needed functions for each fan using the macro defined above
1064 * (4 fans are supported)
1066 sysfs_fan_speeds_offset(1);
1067 sysfs_fan_speeds_offset(2);
1068 sysfs_fan_speeds_offset(3);
1069 sysfs_fan_speeds_offset(4);
1071 static const struct attribute_group fan_attribute_groups[] = {
1072 { .attrs = fan1_attributes },
1073 { .attrs = fan2_attributes },
1074 { .attrs = fan3_attributes },
1075 { .attrs = fan4_attributes },
1079 * Temperature sensors sysfs entries.
1081 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1082 applesmc_show_temperature, NULL, 0);
1083 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1084 applesmc_show_temperature, NULL, 1);
1085 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1086 applesmc_show_temperature, NULL, 2);
1087 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1088 applesmc_show_temperature, NULL, 3);
1089 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1090 applesmc_show_temperature, NULL, 4);
1091 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1092 applesmc_show_temperature, NULL, 5);
1093 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1094 applesmc_show_temperature, NULL, 6);
1095 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1096 applesmc_show_temperature, NULL, 7);
1097 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1098 applesmc_show_temperature, NULL, 8);
1099 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1100 applesmc_show_temperature, NULL, 9);
1101 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1102 applesmc_show_temperature, NULL, 10);
1103 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1104 applesmc_show_temperature, NULL, 11);
1105 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1106 applesmc_show_temperature, NULL, 12);
1107 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1108 applesmc_show_temperature, NULL, 13);
1109 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1110 applesmc_show_temperature, NULL, 14);
1111 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1112 applesmc_show_temperature, NULL, 15);
1113 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1114 applesmc_show_temperature, NULL, 16);
1115 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1116 applesmc_show_temperature, NULL, 17);
1117 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1118 applesmc_show_temperature, NULL, 18);
1119 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1120 applesmc_show_temperature, NULL, 19);
1121 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1122 applesmc_show_temperature, NULL, 20);
1123 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1124 applesmc_show_temperature, NULL, 21);
1125 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1126 applesmc_show_temperature, NULL, 22);
1127 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1128 applesmc_show_temperature, NULL, 23);
1129 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1130 applesmc_show_temperature, NULL, 24);
1131 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1132 applesmc_show_temperature, NULL, 25);
1133 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1134 applesmc_show_temperature, NULL, 26);
1135 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1136 applesmc_show_temperature, NULL, 27);
1137 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1138 applesmc_show_temperature, NULL, 28);
1139 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1140 applesmc_show_temperature, NULL, 29);
1141 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1142 applesmc_show_temperature, NULL, 30);
1143 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1144 applesmc_show_temperature, NULL, 31);
1145 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1146 applesmc_show_temperature, NULL, 32);
1147 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1148 applesmc_show_temperature, NULL, 33);
1149 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1150 applesmc_show_temperature, NULL, 34);
1152 static struct attribute *temperature_attributes[] = {
1153 &sensor_dev_attr_temp1_input.dev_attr.attr,
1154 &sensor_dev_attr_temp2_input.dev_attr.attr,
1155 &sensor_dev_attr_temp3_input.dev_attr.attr,
1156 &sensor_dev_attr_temp4_input.dev_attr.attr,
1157 &sensor_dev_attr_temp5_input.dev_attr.attr,
1158 &sensor_dev_attr_temp6_input.dev_attr.attr,
1159 &sensor_dev_attr_temp7_input.dev_attr.attr,
1160 &sensor_dev_attr_temp8_input.dev_attr.attr,
1161 &sensor_dev_attr_temp9_input.dev_attr.attr,
1162 &sensor_dev_attr_temp10_input.dev_attr.attr,
1163 &sensor_dev_attr_temp11_input.dev_attr.attr,
1164 &sensor_dev_attr_temp12_input.dev_attr.attr,
1165 &sensor_dev_attr_temp13_input.dev_attr.attr,
1166 &sensor_dev_attr_temp14_input.dev_attr.attr,
1167 &sensor_dev_attr_temp15_input.dev_attr.attr,
1168 &sensor_dev_attr_temp16_input.dev_attr.attr,
1169 &sensor_dev_attr_temp17_input.dev_attr.attr,
1170 &sensor_dev_attr_temp18_input.dev_attr.attr,
1171 &sensor_dev_attr_temp19_input.dev_attr.attr,
1172 &sensor_dev_attr_temp20_input.dev_attr.attr,
1173 &sensor_dev_attr_temp21_input.dev_attr.attr,
1174 &sensor_dev_attr_temp22_input.dev_attr.attr,
1175 &sensor_dev_attr_temp23_input.dev_attr.attr,
1176 &sensor_dev_attr_temp24_input.dev_attr.attr,
1177 &sensor_dev_attr_temp25_input.dev_attr.attr,
1178 &sensor_dev_attr_temp26_input.dev_attr.attr,
1179 &sensor_dev_attr_temp27_input.dev_attr.attr,
1180 &sensor_dev_attr_temp28_input.dev_attr.attr,
1181 &sensor_dev_attr_temp29_input.dev_attr.attr,
1182 &sensor_dev_attr_temp30_input.dev_attr.attr,
1183 &sensor_dev_attr_temp31_input.dev_attr.attr,
1184 &sensor_dev_attr_temp32_input.dev_attr.attr,
1185 &sensor_dev_attr_temp33_input.dev_attr.attr,
1186 &sensor_dev_attr_temp34_input.dev_attr.attr,
1187 &sensor_dev_attr_temp35_input.dev_attr.attr,
1191 static const struct attribute_group temperature_attributes_group =
1192 { .attrs = temperature_attributes };
1197 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1199 static int applesmc_dmi_match(const struct dmi_system_id *id)
1202 struct dmi_match_data* dmi_data = id->driver_data;
1203 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1204 applesmc_accelerometer = dmi_data->accelerometer;
1205 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1206 applesmc_accelerometer ? "with" : "without");
1207 applesmc_light = dmi_data->light;
1208 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1209 applesmc_light ? "with" : "without");
1211 applesmc_temperature_set = dmi_data->temperature_set;
1212 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1214 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1218 /* Create accelerometer ressources */
1219 static int applesmc_create_accelerometer(void)
1221 struct input_dev *idev;
1224 ret = sysfs_create_group(&pdev->dev.kobj,
1225 &accelerometer_attributes_group);
1229 applesmc_idev = input_allocate_polled_device();
1230 if (!applesmc_idev) {
1235 applesmc_idev->poll = applesmc_idev_poll;
1236 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1238 /* initial calibrate for the input device */
1239 applesmc_calibrate();
1241 /* initialize the input device */
1242 idev = applesmc_idev->input;
1243 idev->name = "applesmc";
1244 idev->id.bustype = BUS_HOST;
1245 idev->dev.parent = &pdev->dev;
1246 idev->evbit[0] = BIT_MASK(EV_ABS);
1247 input_set_abs_params(idev, ABS_X,
1248 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1249 input_set_abs_params(idev, ABS_Y,
1250 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1252 ret = input_register_polled_device(applesmc_idev);
1259 input_free_polled_device(applesmc_idev);
1262 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1265 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1269 /* Release all ressources used by the accelerometer */
1270 static void applesmc_release_accelerometer(void)
1272 input_unregister_polled_device(applesmc_idev);
1273 input_free_polled_device(applesmc_idev);
1274 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1277 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1278 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1279 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1280 /* MacBook2: accelerometer and temperature set 1 */
1281 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1282 /* MacBook: accelerometer and temperature set 2 */
1283 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1284 /* MacMini: temperature set 3 */
1285 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1286 /* MacPro: temperature set 4 */
1287 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1288 /* iMac: temperature set 5 */
1289 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1290 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1291 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1292 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1293 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1294 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1295 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1296 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1297 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1298 /* iMac 5: light sensor only, temperature set 10 */
1299 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1300 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1301 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
1302 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1303 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
1304 /* iMac 8: light sensor only, temperature set 13 */
1305 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
1306 /* iMac 6: light sensor only, temperature set 14 */
1307 { .accelerometer = 0, .light = 0, .temperature_set = 14 },
1308 /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
1309 { .accelerometer = 1, .light = 1, .temperature_set = 15 },
1312 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1313 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1314 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1315 { applesmc_dmi_match, "Apple MacBook Air 2", {
1316 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1317 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
1318 &applesmc_dmi_data[15]},
1319 { applesmc_dmi_match, "Apple MacBook Air", {
1320 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1321 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1322 &applesmc_dmi_data[7]},
1323 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1324 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1325 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1326 &applesmc_dmi_data[12]},
1327 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1328 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1329 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1330 &applesmc_dmi_data[8]},
1331 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1332 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1333 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1334 &applesmc_dmi_data[9]},
1335 { applesmc_dmi_match, "Apple MacBook Pro", {
1336 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1337 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1338 &applesmc_dmi_data[0]},
1339 { applesmc_dmi_match, "Apple MacBook (v2)", {
1340 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1341 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1342 &applesmc_dmi_data[1]},
1343 { applesmc_dmi_match, "Apple MacBook (v3)", {
1344 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1345 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1346 &applesmc_dmi_data[6]},
1347 { applesmc_dmi_match, "Apple MacBook 4", {
1348 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1349 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1350 &applesmc_dmi_data[6]},
1351 { applesmc_dmi_match, "Apple MacBook 5", {
1352 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1353 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1354 &applesmc_dmi_data[11]},
1355 { applesmc_dmi_match, "Apple MacBook", {
1356 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1357 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1358 &applesmc_dmi_data[2]},
1359 { applesmc_dmi_match, "Apple Macmini", {
1360 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1361 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1362 &applesmc_dmi_data[3]},
1363 { applesmc_dmi_match, "Apple MacPro2", {
1364 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1365 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1366 &applesmc_dmi_data[4]},
1367 { applesmc_dmi_match, "Apple MacPro", {
1368 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1369 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1370 &applesmc_dmi_data[4]},
1371 { applesmc_dmi_match, "Apple iMac 8", {
1372 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1373 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1374 &applesmc_dmi_data[13]},
1375 { applesmc_dmi_match, "Apple iMac 6", {
1376 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1377 DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
1378 &applesmc_dmi_data[14]},
1379 { applesmc_dmi_match, "Apple iMac 5", {
1380 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1381 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1382 &applesmc_dmi_data[10]},
1383 { applesmc_dmi_match, "Apple iMac", {
1384 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1385 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1386 &applesmc_dmi_data[5]},
1390 static int __init applesmc_init(void)
1396 if (!dmi_check_system(applesmc_whitelist)) {
1397 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1402 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1408 ret = platform_driver_register(&applesmc_driver);
1412 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1415 ret = PTR_ERR(pdev);
1419 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1423 /* Create key enumeration sysfs files */
1424 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1428 /* create fan files */
1429 count = applesmc_get_fan_count();
1431 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1433 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1437 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1438 " but at most 4 fans are supported"
1439 " by the driver.\n");
1441 ret = sysfs_create_group(&pdev->dev.kobj,
1442 &fan_attribute_groups[3]);
1444 goto out_key_enumeration;
1446 ret = sysfs_create_group(&pdev->dev.kobj,
1447 &fan_attribute_groups[2]);
1449 goto out_key_enumeration;
1451 ret = sysfs_create_group(&pdev->dev.kobj,
1452 &fan_attribute_groups[1]);
1454 goto out_key_enumeration;
1456 ret = sysfs_create_group(&pdev->dev.kobj,
1457 &fan_attribute_groups[0]);
1466 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1468 if (temperature_attributes[i] == NULL) {
1469 printk(KERN_ERR "applesmc: More temperature sensors "
1470 "in temperature_sensors_sets (at least %i)"
1471 "than available sysfs files in "
1472 "temperature_attributes (%i), please report "
1473 "this bug.\n", i, i-1);
1474 goto out_temperature;
1476 ret = sysfs_create_file(&pdev->dev.kobj,
1477 temperature_attributes[i]);
1479 goto out_temperature;
1482 if (applesmc_accelerometer) {
1483 ret = applesmc_create_accelerometer();
1485 goto out_temperature;
1488 if (applesmc_light) {
1489 /* Add light sensor file */
1490 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1492 goto out_accelerometer;
1494 /* Create the workqueue */
1495 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1496 if (!applesmc_led_wq) {
1498 goto out_light_sysfs;
1501 /* register as a led device */
1502 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1507 hwmon_dev = hwmon_device_register(&pdev->dev);
1508 if (IS_ERR(hwmon_dev)) {
1509 ret = PTR_ERR(hwmon_dev);
1510 goto out_light_ledclass;
1513 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1519 led_classdev_unregister(&applesmc_backlight);
1522 destroy_workqueue(applesmc_led_wq);
1525 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1527 if (applesmc_accelerometer)
1528 applesmc_release_accelerometer();
1530 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1531 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1533 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1534 out_key_enumeration:
1535 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1537 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1539 platform_device_unregister(pdev);
1541 platform_driver_unregister(&applesmc_driver);
1543 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1545 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1549 static void __exit applesmc_exit(void)
1551 hwmon_device_unregister(hwmon_dev);
1552 if (applesmc_light) {
1553 led_classdev_unregister(&applesmc_backlight);
1554 destroy_workqueue(applesmc_led_wq);
1555 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1557 if (applesmc_accelerometer)
1558 applesmc_release_accelerometer();
1559 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1560 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1561 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1562 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1563 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1564 platform_device_unregister(pdev);
1565 platform_driver_unregister(&applesmc_driver);
1566 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1568 printk(KERN_INFO "applesmc: driver unloaded.\n");
1571 module_init(applesmc_init);
1572 module_exit(applesmc_exit);
1574 MODULE_AUTHOR("Nicolas Boichat");
1575 MODULE_DESCRIPTION("Apple SMC");
1576 MODULE_LICENSE("GPL v2");
1577 MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);