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 },
136 /* List of keys used to read/write fan speeds */
137 static const char* fan_speed_keys[] = {
145 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
146 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
148 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
149 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
150 #define APPLESMC_INPUT_FLAT 4
156 /* Structure to be passed to DMI_MATCH function */
157 struct dmi_match_data {
158 /* Indicates whether this computer has an accelerometer. */
160 /* Indicates whether this computer has light sensors and keyboard backlight. */
162 /* Indicates which temperature sensors set to use. */
166 static const int debug;
167 static struct platform_device *pdev;
170 static struct device *hwmon_dev;
171 static struct input_polled_dev *applesmc_idev;
173 /* Indicates whether this computer has an accelerometer. */
174 static unsigned int applesmc_accelerometer;
176 /* Indicates whether this computer has light sensors and keyboard backlight. */
177 static unsigned int applesmc_light;
179 /* Indicates which temperature sensors set to use. */
180 static unsigned int applesmc_temperature_set;
182 static DEFINE_MUTEX(applesmc_lock);
185 * Last index written to key_at_index sysfs file, and value to use for all other
186 * key_at_index_* sysfs files.
188 static unsigned int key_at_index;
190 static struct workqueue_struct *applesmc_led_wq;
193 * __wait_status - Wait up to 32ms for the status port to get a certain value
194 * (masked with 0x0f), returning zero if the value is obtained. Callers must
195 * hold applesmc_lock.
197 static int __wait_status(u8 val)
201 val = val & APPLESMC_STATUS_MASK;
203 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
205 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
208 "Waited %d us for status %x\n",
209 2 * us - APPLESMC_MIN_WAIT, val);
214 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
215 val, inb(APPLESMC_CMD_PORT));
221 * special treatment of command port - on newer macbooks, it seems necessary
222 * to resend the command byte before polling the status again. Callers must
223 * hold applesmc_lock.
225 static int send_command(u8 cmd)
228 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
229 outb(cmd, APPLESMC_CMD_PORT);
231 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
234 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
235 cmd, inb(APPLESMC_CMD_PORT));
240 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
241 * Returns zero on success or a negative error on failure. Callers must
242 * hold applesmc_lock.
244 static int applesmc_read_key(const char* key, u8* buffer, u8 len)
248 if (len > APPLESMC_MAX_DATA_LENGTH) {
249 printk(KERN_ERR "applesmc_read_key: cannot read more than "
250 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
254 if (send_command(APPLESMC_READ_CMD))
257 for (i = 0; i < 4; i++) {
258 outb(key[i], APPLESMC_DATA_PORT);
259 if (__wait_status(0x04))
263 printk(KERN_DEBUG "<%s", key);
265 outb(len, APPLESMC_DATA_PORT);
267 printk(KERN_DEBUG ">%x", len);
269 for (i = 0; i < len; i++) {
270 if (__wait_status(0x05))
272 buffer[i] = inb(APPLESMC_DATA_PORT);
274 printk(KERN_DEBUG "<%x", buffer[i]);
277 printk(KERN_DEBUG "\n");
283 * applesmc_write_key - writes len bytes from buffer to a given key.
284 * Returns zero on success or a negative error on failure. Callers must
285 * hold applesmc_lock.
287 static int applesmc_write_key(const char* key, u8* buffer, u8 len)
291 if (len > APPLESMC_MAX_DATA_LENGTH) {
292 printk(KERN_ERR "applesmc_write_key: cannot write more than "
293 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
297 if (send_command(APPLESMC_WRITE_CMD))
300 for (i = 0; i < 4; i++) {
301 outb(key[i], APPLESMC_DATA_PORT);
302 if (__wait_status(0x04))
306 outb(len, APPLESMC_DATA_PORT);
308 for (i = 0; i < len; i++) {
309 if (__wait_status(0x04))
311 outb(buffer[i], APPLESMC_DATA_PORT);
318 * applesmc_get_key_at_index - get key at index, and put the result in key
319 * (char[6]). Returns zero on success or a negative error on failure. Callers
320 * must hold applesmc_lock.
322 static int applesmc_get_key_at_index(int index, char* key)
326 readkey[0] = index >> 24;
327 readkey[1] = index >> 16;
328 readkey[2] = index >> 8;
331 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
334 for (i = 0; i < 4; i++) {
335 outb(readkey[i], APPLESMC_DATA_PORT);
336 if (__wait_status(0x04))
340 outb(4, APPLESMC_DATA_PORT);
342 for (i = 0; i < 4; i++) {
343 if (__wait_status(0x05))
345 key[i] = inb(APPLESMC_DATA_PORT);
353 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
354 * Returns zero on success or a negative error on failure. Callers must
355 * hold applesmc_lock.
357 static int applesmc_get_key_type(char* key, char* type)
361 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
364 for (i = 0; i < 4; i++) {
365 outb(key[i], APPLESMC_DATA_PORT);
366 if (__wait_status(0x04))
370 outb(6, APPLESMC_DATA_PORT);
372 for (i = 0; i < 6; i++) {
373 if (__wait_status(0x05))
375 type[i] = inb(APPLESMC_DATA_PORT);
383 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
384 * hold applesmc_lock.
386 static int applesmc_read_motion_sensor(int index, s16* value)
393 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
396 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
399 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
405 *value = ((s16)buffer[0] << 8) | buffer[1];
411 * applesmc_device_init - initialize the accelerometer. Returns zero on success
412 * and negative error code on failure. Can sleep.
414 static int applesmc_device_init(void)
416 int total, ret = -ENXIO;
419 if (!applesmc_accelerometer)
422 mutex_lock(&applesmc_lock);
424 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
426 printk(KERN_DEBUG "applesmc try %d\n", total);
427 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
428 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
429 if (total == INIT_TIMEOUT_MSECS) {
430 printk(KERN_DEBUG "applesmc: device has"
431 " already been initialized"
432 " (0x%02x, 0x%02x).\n",
433 buffer[0], buffer[1]);
435 printk(KERN_DEBUG "applesmc: device"
436 " successfully initialized"
437 " (0x%02x, 0x%02x).\n",
438 buffer[0], buffer[1]);
445 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
446 msleep(INIT_WAIT_MSECS);
449 printk(KERN_WARNING "applesmc: failed to init the device\n");
452 mutex_unlock(&applesmc_lock);
457 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
460 static int applesmc_get_fan_count(void)
465 mutex_lock(&applesmc_lock);
467 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
469 mutex_unlock(&applesmc_lock);
476 /* Device model stuff */
477 static int applesmc_probe(struct platform_device *dev)
481 ret = applesmc_device_init();
485 printk(KERN_INFO "applesmc: device successfully initialized.\n");
489 static int applesmc_resume(struct platform_device *dev)
491 return applesmc_device_init();
494 static struct platform_driver applesmc_driver = {
495 .probe = applesmc_probe,
496 .resume = applesmc_resume,
499 .owner = THIS_MODULE,
504 * applesmc_calibrate - Set our "resting" values. Callers must
505 * hold applesmc_lock.
507 static void applesmc_calibrate(void)
509 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
510 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
514 static void applesmc_idev_poll(struct input_polled_dev *dev)
516 struct input_dev *idev = dev->input;
519 mutex_lock(&applesmc_lock);
521 if (applesmc_read_motion_sensor(SENSOR_X, &x))
523 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
527 input_report_abs(idev, ABS_X, x - rest_x);
528 input_report_abs(idev, ABS_Y, y - rest_y);
532 mutex_unlock(&applesmc_lock);
537 static ssize_t applesmc_name_show(struct device *dev,
538 struct device_attribute *attr, char *buf)
540 return snprintf(buf, PAGE_SIZE, "applesmc\n");
543 static ssize_t applesmc_position_show(struct device *dev,
544 struct device_attribute *attr, char *buf)
549 mutex_lock(&applesmc_lock);
551 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
554 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
557 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
562 mutex_unlock(&applesmc_lock);
566 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
569 static ssize_t applesmc_light_show(struct device *dev,
570 struct device_attribute *attr, char *sysfsbuf)
572 static int data_length;
574 u8 left = 0, right = 0;
575 u8 buffer[10], query[6];
577 mutex_lock(&applesmc_lock);
580 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
583 data_length = clamp_val(query[0], 0, 10);
584 printk(KERN_INFO "applesmc: light sensor data length set to "
585 "%d\n", data_length);
588 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
592 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
596 mutex_unlock(&applesmc_lock);
600 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
603 /* Displays degree Celsius * 1000 */
604 static ssize_t applesmc_show_temperature(struct device *dev,
605 struct device_attribute *devattr, char *sysfsbuf)
610 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
612 temperature_sensors_sets[applesmc_temperature_set][attr->index];
614 mutex_lock(&applesmc_lock);
616 ret = applesmc_read_key(key, buffer, 2);
617 temp = buffer[0]*1000;
618 temp += (buffer[1] >> 6) * 250;
620 mutex_unlock(&applesmc_lock);
625 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
628 static ssize_t applesmc_show_fan_speed(struct device *dev,
629 struct device_attribute *attr, char *sysfsbuf)
632 unsigned int speed = 0;
635 struct sensor_device_attribute_2 *sensor_attr =
636 to_sensor_dev_attr_2(attr);
638 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
639 newkey[1] = '0' + sensor_attr->index;
640 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
641 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
644 mutex_lock(&applesmc_lock);
646 ret = applesmc_read_key(newkey, buffer, 2);
647 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
649 mutex_unlock(&applesmc_lock);
653 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
656 static ssize_t applesmc_store_fan_speed(struct device *dev,
657 struct device_attribute *attr,
658 const char *sysfsbuf, size_t count)
664 struct sensor_device_attribute_2 *sensor_attr =
665 to_sensor_dev_attr_2(attr);
667 speed = simple_strtoul(sysfsbuf, NULL, 10);
669 if (speed > 0x4000) /* Bigger than a 14-bit value */
672 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
673 newkey[1] = '0' + sensor_attr->index;
674 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
675 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
678 mutex_lock(&applesmc_lock);
680 buffer[0] = (speed >> 6) & 0xff;
681 buffer[1] = (speed << 2) & 0xff;
682 ret = applesmc_write_key(newkey, buffer, 2);
684 mutex_unlock(&applesmc_lock);
691 static ssize_t applesmc_show_fan_manual(struct device *dev,
692 struct device_attribute *devattr, char *sysfsbuf)
697 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
699 mutex_lock(&applesmc_lock);
701 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
702 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
704 mutex_unlock(&applesmc_lock);
708 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
711 static ssize_t applesmc_store_fan_manual(struct device *dev,
712 struct device_attribute *devattr,
713 const char *sysfsbuf, size_t count)
719 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
721 input = simple_strtoul(sysfsbuf, NULL, 10);
723 mutex_lock(&applesmc_lock);
725 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
726 val = (buffer[0] << 8 | buffer[1]);
731 val = val | (0x01 << attr->index);
733 val = val & ~(0x01 << attr->index);
735 buffer[0] = (val >> 8) & 0xFF;
736 buffer[1] = val & 0xFF;
738 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
741 mutex_unlock(&applesmc_lock);
748 static ssize_t applesmc_show_fan_position(struct device *dev,
749 struct device_attribute *attr, char *sysfsbuf)
754 struct sensor_device_attribute_2 *sensor_attr =
755 to_sensor_dev_attr_2(attr);
757 newkey[0] = FAN_POSITION[0];
758 newkey[1] = '0' + sensor_attr->index;
759 newkey[2] = FAN_POSITION[2];
760 newkey[3] = FAN_POSITION[3];
763 mutex_lock(&applesmc_lock);
765 ret = applesmc_read_key(newkey, buffer, 16);
768 mutex_unlock(&applesmc_lock);
772 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
775 static ssize_t applesmc_calibrate_show(struct device *dev,
776 struct device_attribute *attr, char *sysfsbuf)
778 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
781 static ssize_t applesmc_calibrate_store(struct device *dev,
782 struct device_attribute *attr, const char *sysfsbuf, size_t count)
784 mutex_lock(&applesmc_lock);
785 applesmc_calibrate();
786 mutex_unlock(&applesmc_lock);
791 /* Store the next backlight value to be written by the work */
792 static unsigned int backlight_value;
794 static void applesmc_backlight_set(struct work_struct *work)
798 mutex_lock(&applesmc_lock);
799 buffer[0] = backlight_value;
801 applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
802 mutex_unlock(&applesmc_lock);
804 static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
806 static void applesmc_brightness_set(struct led_classdev *led_cdev,
807 enum led_brightness value)
811 backlight_value = value;
812 ret = queue_work(applesmc_led_wq, &backlight_work);
815 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
818 static ssize_t applesmc_key_count_show(struct device *dev,
819 struct device_attribute *attr, char *sysfsbuf)
825 mutex_lock(&applesmc_lock);
827 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
828 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
829 ((u32)buffer[2]<<8) + buffer[3];
831 mutex_unlock(&applesmc_lock);
835 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
838 static ssize_t applesmc_key_at_index_read_show(struct device *dev,
839 struct device_attribute *attr, char *sysfsbuf)
845 mutex_lock(&applesmc_lock);
847 ret = applesmc_get_key_at_index(key_at_index, key);
849 if (ret || !key[0]) {
850 mutex_unlock(&applesmc_lock);
855 ret = applesmc_get_key_type(key, info);
858 mutex_unlock(&applesmc_lock);
864 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
865 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
867 ret = applesmc_read_key(key, sysfsbuf, info[0]);
869 mutex_unlock(&applesmc_lock);
878 static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
879 struct device_attribute *attr, char *sysfsbuf)
885 mutex_lock(&applesmc_lock);
887 ret = applesmc_get_key_at_index(key_at_index, key);
889 if (ret || !key[0]) {
890 mutex_unlock(&applesmc_lock);
895 ret = applesmc_get_key_type(key, info);
897 mutex_unlock(&applesmc_lock);
900 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
905 static ssize_t applesmc_key_at_index_type_show(struct device *dev,
906 struct device_attribute *attr, char *sysfsbuf)
912 mutex_lock(&applesmc_lock);
914 ret = applesmc_get_key_at_index(key_at_index, key);
916 if (ret || !key[0]) {
917 mutex_unlock(&applesmc_lock);
922 ret = applesmc_get_key_type(key, info);
924 mutex_unlock(&applesmc_lock);
927 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
932 static ssize_t applesmc_key_at_index_name_show(struct device *dev,
933 struct device_attribute *attr, char *sysfsbuf)
938 mutex_lock(&applesmc_lock);
940 ret = applesmc_get_key_at_index(key_at_index, key);
942 mutex_unlock(&applesmc_lock);
945 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
950 static ssize_t applesmc_key_at_index_show(struct device *dev,
951 struct device_attribute *attr, char *sysfsbuf)
953 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
956 static ssize_t applesmc_key_at_index_store(struct device *dev,
957 struct device_attribute *attr, const char *sysfsbuf, size_t count)
959 mutex_lock(&applesmc_lock);
961 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
963 mutex_unlock(&applesmc_lock);
968 static struct led_classdev applesmc_backlight = {
969 .name = "smc::kbd_backlight",
970 .default_trigger = "nand-disk",
971 .brightness_set = applesmc_brightness_set,
974 static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
976 static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
977 static DEVICE_ATTR(calibrate, 0644,
978 applesmc_calibrate_show, applesmc_calibrate_store);
980 static struct attribute *accelerometer_attributes[] = {
981 &dev_attr_position.attr,
982 &dev_attr_calibrate.attr,
986 static const struct attribute_group accelerometer_attributes_group =
987 { .attrs = accelerometer_attributes };
989 static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
991 static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
992 static DEVICE_ATTR(key_at_index, 0644,
993 applesmc_key_at_index_show, applesmc_key_at_index_store);
994 static DEVICE_ATTR(key_at_index_name, 0444,
995 applesmc_key_at_index_name_show, NULL);
996 static DEVICE_ATTR(key_at_index_type, 0444,
997 applesmc_key_at_index_type_show, NULL);
998 static DEVICE_ATTR(key_at_index_data_length, 0444,
999 applesmc_key_at_index_data_length_show, NULL);
1000 static DEVICE_ATTR(key_at_index_data, 0444,
1001 applesmc_key_at_index_read_show, NULL);
1003 static struct attribute *key_enumeration_attributes[] = {
1004 &dev_attr_key_count.attr,
1005 &dev_attr_key_at_index.attr,
1006 &dev_attr_key_at_index_name.attr,
1007 &dev_attr_key_at_index_type.attr,
1008 &dev_attr_key_at_index_data_length.attr,
1009 &dev_attr_key_at_index_data.attr,
1013 static const struct attribute_group key_enumeration_group =
1014 { .attrs = key_enumeration_attributes };
1017 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1018 * - show actual speed
1019 * - show/store minimum speed
1020 * - show maximum speed
1022 * - show/store target speed
1023 * - show/store manual mode
1025 #define sysfs_fan_speeds_offset(offset) \
1026 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1027 applesmc_show_fan_speed, NULL, 0, offset-1); \
1029 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1030 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1032 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1033 applesmc_show_fan_speed, NULL, 2, offset-1); \
1035 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1036 applesmc_show_fan_speed, NULL, 3, offset-1); \
1038 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1039 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1041 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1042 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1044 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1045 applesmc_show_fan_position, NULL, offset-1); \
1047 static struct attribute *fan##offset##_attributes[] = { \
1048 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1049 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1050 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1051 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1052 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1053 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1054 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1059 * Create the needed functions for each fan using the macro defined above
1060 * (4 fans are supported)
1062 sysfs_fan_speeds_offset(1);
1063 sysfs_fan_speeds_offset(2);
1064 sysfs_fan_speeds_offset(3);
1065 sysfs_fan_speeds_offset(4);
1067 static const struct attribute_group fan_attribute_groups[] = {
1068 { .attrs = fan1_attributes },
1069 { .attrs = fan2_attributes },
1070 { .attrs = fan3_attributes },
1071 { .attrs = fan4_attributes },
1075 * Temperature sensors sysfs entries.
1077 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1078 applesmc_show_temperature, NULL, 0);
1079 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1080 applesmc_show_temperature, NULL, 1);
1081 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1082 applesmc_show_temperature, NULL, 2);
1083 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1084 applesmc_show_temperature, NULL, 3);
1085 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1086 applesmc_show_temperature, NULL, 4);
1087 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1088 applesmc_show_temperature, NULL, 5);
1089 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1090 applesmc_show_temperature, NULL, 6);
1091 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1092 applesmc_show_temperature, NULL, 7);
1093 static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1094 applesmc_show_temperature, NULL, 8);
1095 static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1096 applesmc_show_temperature, NULL, 9);
1097 static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1098 applesmc_show_temperature, NULL, 10);
1099 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1100 applesmc_show_temperature, NULL, 11);
1101 static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1102 applesmc_show_temperature, NULL, 12);
1103 static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1104 applesmc_show_temperature, NULL, 13);
1105 static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1106 applesmc_show_temperature, NULL, 14);
1107 static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1108 applesmc_show_temperature, NULL, 15);
1109 static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1110 applesmc_show_temperature, NULL, 16);
1111 static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1112 applesmc_show_temperature, NULL, 17);
1113 static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1114 applesmc_show_temperature, NULL, 18);
1115 static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1116 applesmc_show_temperature, NULL, 19);
1117 static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1118 applesmc_show_temperature, NULL, 20);
1119 static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1120 applesmc_show_temperature, NULL, 21);
1121 static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1122 applesmc_show_temperature, NULL, 22);
1123 static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1124 applesmc_show_temperature, NULL, 23);
1125 static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1126 applesmc_show_temperature, NULL, 24);
1127 static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1128 applesmc_show_temperature, NULL, 25);
1129 static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1130 applesmc_show_temperature, NULL, 26);
1131 static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1132 applesmc_show_temperature, NULL, 27);
1133 static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1134 applesmc_show_temperature, NULL, 28);
1135 static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1136 applesmc_show_temperature, NULL, 29);
1137 static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1138 applesmc_show_temperature, NULL, 30);
1139 static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1140 applesmc_show_temperature, NULL, 31);
1141 static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1142 applesmc_show_temperature, NULL, 32);
1143 static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1144 applesmc_show_temperature, NULL, 33);
1145 static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1146 applesmc_show_temperature, NULL, 34);
1148 static struct attribute *temperature_attributes[] = {
1149 &sensor_dev_attr_temp1_input.dev_attr.attr,
1150 &sensor_dev_attr_temp2_input.dev_attr.attr,
1151 &sensor_dev_attr_temp3_input.dev_attr.attr,
1152 &sensor_dev_attr_temp4_input.dev_attr.attr,
1153 &sensor_dev_attr_temp5_input.dev_attr.attr,
1154 &sensor_dev_attr_temp6_input.dev_attr.attr,
1155 &sensor_dev_attr_temp7_input.dev_attr.attr,
1156 &sensor_dev_attr_temp8_input.dev_attr.attr,
1157 &sensor_dev_attr_temp9_input.dev_attr.attr,
1158 &sensor_dev_attr_temp10_input.dev_attr.attr,
1159 &sensor_dev_attr_temp11_input.dev_attr.attr,
1160 &sensor_dev_attr_temp12_input.dev_attr.attr,
1161 &sensor_dev_attr_temp13_input.dev_attr.attr,
1162 &sensor_dev_attr_temp14_input.dev_attr.attr,
1163 &sensor_dev_attr_temp15_input.dev_attr.attr,
1164 &sensor_dev_attr_temp16_input.dev_attr.attr,
1165 &sensor_dev_attr_temp17_input.dev_attr.attr,
1166 &sensor_dev_attr_temp18_input.dev_attr.attr,
1167 &sensor_dev_attr_temp19_input.dev_attr.attr,
1168 &sensor_dev_attr_temp20_input.dev_attr.attr,
1169 &sensor_dev_attr_temp21_input.dev_attr.attr,
1170 &sensor_dev_attr_temp22_input.dev_attr.attr,
1171 &sensor_dev_attr_temp23_input.dev_attr.attr,
1172 &sensor_dev_attr_temp24_input.dev_attr.attr,
1173 &sensor_dev_attr_temp25_input.dev_attr.attr,
1174 &sensor_dev_attr_temp26_input.dev_attr.attr,
1175 &sensor_dev_attr_temp27_input.dev_attr.attr,
1176 &sensor_dev_attr_temp28_input.dev_attr.attr,
1177 &sensor_dev_attr_temp29_input.dev_attr.attr,
1178 &sensor_dev_attr_temp30_input.dev_attr.attr,
1179 &sensor_dev_attr_temp31_input.dev_attr.attr,
1180 &sensor_dev_attr_temp32_input.dev_attr.attr,
1181 &sensor_dev_attr_temp33_input.dev_attr.attr,
1182 &sensor_dev_attr_temp34_input.dev_attr.attr,
1183 &sensor_dev_attr_temp35_input.dev_attr.attr,
1187 static const struct attribute_group temperature_attributes_group =
1188 { .attrs = temperature_attributes };
1193 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1195 static int applesmc_dmi_match(const struct dmi_system_id *id)
1198 struct dmi_match_data* dmi_data = id->driver_data;
1199 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1200 applesmc_accelerometer = dmi_data->accelerometer;
1201 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1202 applesmc_accelerometer ? "with" : "without");
1203 applesmc_light = dmi_data->light;
1204 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1205 applesmc_light ? "with" : "without");
1207 applesmc_temperature_set = dmi_data->temperature_set;
1208 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1210 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1214 /* Create accelerometer ressources */
1215 static int applesmc_create_accelerometer(void)
1217 struct input_dev *idev;
1220 ret = sysfs_create_group(&pdev->dev.kobj,
1221 &accelerometer_attributes_group);
1225 applesmc_idev = input_allocate_polled_device();
1226 if (!applesmc_idev) {
1231 applesmc_idev->poll = applesmc_idev_poll;
1232 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1234 /* initial calibrate for the input device */
1235 applesmc_calibrate();
1237 /* initialize the input device */
1238 idev = applesmc_idev->input;
1239 idev->name = "applesmc";
1240 idev->id.bustype = BUS_HOST;
1241 idev->dev.parent = &pdev->dev;
1242 idev->evbit[0] = BIT_MASK(EV_ABS);
1243 input_set_abs_params(idev, ABS_X,
1244 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1245 input_set_abs_params(idev, ABS_Y,
1246 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1248 ret = input_register_polled_device(applesmc_idev);
1255 input_free_polled_device(applesmc_idev);
1258 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1261 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1265 /* Release all ressources used by the accelerometer */
1266 static void applesmc_release_accelerometer(void)
1268 input_unregister_polled_device(applesmc_idev);
1269 input_free_polled_device(applesmc_idev);
1270 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1273 static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1274 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1275 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1276 /* MacBook2: accelerometer and temperature set 1 */
1277 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
1278 /* MacBook: accelerometer and temperature set 2 */
1279 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1280 /* MacMini: temperature set 3 */
1281 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1282 /* MacPro: temperature set 4 */
1283 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1284 /* iMac: temperature set 5 */
1285 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1286 /* MacBook3, MacBook4: accelerometer and temperature set 6 */
1287 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1288 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1289 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
1290 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1291 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
1292 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1293 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
1294 /* iMac 5: light sensor only, temperature set 10 */
1295 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
1296 /* MacBook 5: accelerometer, backlight and temperature set 11 */
1297 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
1298 /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1299 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
1300 /* iMac 8: light sensor only, temperature set 13 */
1301 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
1302 /* iMac 6: light sensor only, temperature set 14 */
1303 { .accelerometer = 0, .light = 0, .temperature_set = 14 },
1306 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1307 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1308 static __initdata struct dmi_system_id applesmc_whitelist[] = {
1309 { applesmc_dmi_match, "Apple MacBook Air", {
1310 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1311 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1312 &applesmc_dmi_data[7]},
1313 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1314 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1315 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1316 &applesmc_dmi_data[12]},
1317 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1318 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1319 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1320 &applesmc_dmi_data[8]},
1321 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1322 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1323 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1324 &applesmc_dmi_data[9]},
1325 { applesmc_dmi_match, "Apple MacBook Pro", {
1326 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1327 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1328 &applesmc_dmi_data[0]},
1329 { applesmc_dmi_match, "Apple MacBook (v2)", {
1330 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1331 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1332 &applesmc_dmi_data[1]},
1333 { applesmc_dmi_match, "Apple MacBook (v3)", {
1334 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1335 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1336 &applesmc_dmi_data[6]},
1337 { applesmc_dmi_match, "Apple MacBook 4", {
1338 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1339 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1340 &applesmc_dmi_data[6]},
1341 { applesmc_dmi_match, "Apple MacBook 5", {
1342 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1343 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1344 &applesmc_dmi_data[11]},
1345 { applesmc_dmi_match, "Apple MacBook", {
1346 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1347 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1348 &applesmc_dmi_data[2]},
1349 { applesmc_dmi_match, "Apple Macmini", {
1350 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1351 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1352 &applesmc_dmi_data[3]},
1353 { applesmc_dmi_match, "Apple MacPro2", {
1354 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1355 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1356 &applesmc_dmi_data[4]},
1357 { applesmc_dmi_match, "Apple MacPro", {
1358 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1359 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1360 &applesmc_dmi_data[4]},
1361 { applesmc_dmi_match, "Apple iMac 8", {
1362 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1363 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1364 &applesmc_dmi_data[13]},
1365 { applesmc_dmi_match, "Apple iMac 6", {
1366 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1367 DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
1368 &applesmc_dmi_data[14]},
1369 { applesmc_dmi_match, "Apple iMac 5", {
1370 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1371 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1372 &applesmc_dmi_data[10]},
1373 { applesmc_dmi_match, "Apple iMac", {
1374 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1375 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1376 &applesmc_dmi_data[5]},
1380 static int __init applesmc_init(void)
1386 if (!dmi_check_system(applesmc_whitelist)) {
1387 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1392 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1398 ret = platform_driver_register(&applesmc_driver);
1402 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1405 ret = PTR_ERR(pdev);
1409 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1413 /* Create key enumeration sysfs files */
1414 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1418 /* create fan files */
1419 count = applesmc_get_fan_count();
1421 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1423 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1427 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1428 " but at most 4 fans are supported"
1429 " by the driver.\n");
1431 ret = sysfs_create_group(&pdev->dev.kobj,
1432 &fan_attribute_groups[3]);
1434 goto out_key_enumeration;
1436 ret = sysfs_create_group(&pdev->dev.kobj,
1437 &fan_attribute_groups[2]);
1439 goto out_key_enumeration;
1441 ret = sysfs_create_group(&pdev->dev.kobj,
1442 &fan_attribute_groups[1]);
1444 goto out_key_enumeration;
1446 ret = sysfs_create_group(&pdev->dev.kobj,
1447 &fan_attribute_groups[0]);
1456 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1458 if (temperature_attributes[i] == NULL) {
1459 printk(KERN_ERR "applesmc: More temperature sensors "
1460 "in temperature_sensors_sets (at least %i)"
1461 "than available sysfs files in "
1462 "temperature_attributes (%i), please report "
1463 "this bug.\n", i, i-1);
1464 goto out_temperature;
1466 ret = sysfs_create_file(&pdev->dev.kobj,
1467 temperature_attributes[i]);
1469 goto out_temperature;
1472 if (applesmc_accelerometer) {
1473 ret = applesmc_create_accelerometer();
1475 goto out_temperature;
1478 if (applesmc_light) {
1479 /* Add light sensor file */
1480 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1482 goto out_accelerometer;
1484 /* Create the workqueue */
1485 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1486 if (!applesmc_led_wq) {
1488 goto out_light_sysfs;
1491 /* register as a led device */
1492 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1497 hwmon_dev = hwmon_device_register(&pdev->dev);
1498 if (IS_ERR(hwmon_dev)) {
1499 ret = PTR_ERR(hwmon_dev);
1500 goto out_light_ledclass;
1503 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1509 led_classdev_unregister(&applesmc_backlight);
1512 destroy_workqueue(applesmc_led_wq);
1515 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1517 if (applesmc_accelerometer)
1518 applesmc_release_accelerometer();
1520 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1521 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1523 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1524 out_key_enumeration:
1525 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1527 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1529 platform_device_unregister(pdev);
1531 platform_driver_unregister(&applesmc_driver);
1533 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1535 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1539 static void __exit applesmc_exit(void)
1541 hwmon_device_unregister(hwmon_dev);
1542 if (applesmc_light) {
1543 led_classdev_unregister(&applesmc_backlight);
1544 destroy_workqueue(applesmc_led_wq);
1545 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1547 if (applesmc_accelerometer)
1548 applesmc_release_accelerometer();
1549 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1550 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1551 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1552 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1553 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1554 platform_device_unregister(pdev);
1555 platform_driver_unregister(&applesmc_driver);
1556 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1558 printk(KERN_INFO "applesmc: driver unloaded.\n");
1561 module_init(applesmc_init);
1562 module_exit(applesmc_exit);
1564 MODULE_AUTHOR("Nicolas Boichat");
1565 MODULE_DESCRIPTION("Apple SMC");
1566 MODULE_LICENSE("GPL v2");
1567 MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);