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
},
121 /* List of keys used to read/write fan speeds */
122 static const char* fan_speed_keys
[] = {
130 #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
131 #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
133 #define APPLESMC_POLL_INTERVAL 50 /* msecs */
134 #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
135 #define APPLESMC_INPUT_FLAT 4
141 /* Structure to be passed to DMI_MATCH function */
142 struct dmi_match_data
{
143 /* Indicates whether this computer has an accelerometer. */
145 /* Indicates whether this computer has light sensors and keyboard backlight. */
147 /* Indicates which temperature sensors set to use. */
151 static const int debug
;
152 static struct platform_device
*pdev
;
155 static struct device
*hwmon_dev
;
156 static struct input_polled_dev
*applesmc_idev
;
158 /* Indicates whether this computer has an accelerometer. */
159 static unsigned int applesmc_accelerometer
;
161 /* Indicates whether this computer has light sensors and keyboard backlight. */
162 static unsigned int applesmc_light
;
164 /* Indicates which temperature sensors set to use. */
165 static unsigned int applesmc_temperature_set
;
167 static DEFINE_MUTEX(applesmc_lock
);
170 * Last index written to key_at_index sysfs file, and value to use for all other
171 * key_at_index_* sysfs files.
173 static unsigned int key_at_index
;
175 static struct workqueue_struct
*applesmc_led_wq
;
178 * __wait_status - Wait up to 32ms for the status port to get a certain value
179 * (masked with 0x0f), returning zero if the value is obtained. Callers must
180 * hold applesmc_lock.
182 static int __wait_status(u8 val
)
186 val
= val
& APPLESMC_STATUS_MASK
;
188 for (us
= APPLESMC_MIN_WAIT
; us
< APPLESMC_MAX_WAIT
; us
<<= 1) {
190 if ((inb(APPLESMC_CMD_PORT
) & APPLESMC_STATUS_MASK
) == val
) {
193 "Waited %d us for status %x\n",
194 2 * us
- APPLESMC_MIN_WAIT
, val
);
199 printk(KERN_WARNING
"applesmc: wait status failed: %x != %x\n",
200 val
, inb(APPLESMC_CMD_PORT
));
206 * special treatment of command port - on newer macbooks, it seems necessary
207 * to resend the command byte before polling the status again. Callers must
208 * hold applesmc_lock.
210 static int send_command(u8 cmd
)
213 for (us
= APPLESMC_MIN_WAIT
; us
< APPLESMC_MAX_WAIT
; us
<<= 1) {
214 outb(cmd
, APPLESMC_CMD_PORT
);
216 if ((inb(APPLESMC_CMD_PORT
) & APPLESMC_STATUS_MASK
) == 0x0c)
219 printk(KERN_WARNING
"applesmc: command failed: %x -> %x\n",
220 cmd
, inb(APPLESMC_CMD_PORT
));
225 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
226 * Returns zero on success or a negative error on failure. Callers must
227 * hold applesmc_lock.
229 static int applesmc_read_key(const char* key
, u8
* buffer
, u8 len
)
233 if (len
> APPLESMC_MAX_DATA_LENGTH
) {
234 printk(KERN_ERR
"applesmc_read_key: cannot read more than "
235 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH
);
239 if (send_command(APPLESMC_READ_CMD
))
242 for (i
= 0; i
< 4; i
++) {
243 outb(key
[i
], APPLESMC_DATA_PORT
);
244 if (__wait_status(0x04))
248 printk(KERN_DEBUG
"<%s", key
);
250 outb(len
, APPLESMC_DATA_PORT
);
252 printk(KERN_DEBUG
">%x", len
);
254 for (i
= 0; i
< len
; i
++) {
255 if (__wait_status(0x05))
257 buffer
[i
] = inb(APPLESMC_DATA_PORT
);
259 printk(KERN_DEBUG
"<%x", buffer
[i
]);
262 printk(KERN_DEBUG
"\n");
268 * applesmc_write_key - writes len bytes from buffer to a given key.
269 * Returns zero on success or a negative error on failure. Callers must
270 * hold applesmc_lock.
272 static int applesmc_write_key(const char* key
, u8
* buffer
, u8 len
)
276 if (len
> APPLESMC_MAX_DATA_LENGTH
) {
277 printk(KERN_ERR
"applesmc_write_key: cannot write more than "
278 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH
);
282 if (send_command(APPLESMC_WRITE_CMD
))
285 for (i
= 0; i
< 4; i
++) {
286 outb(key
[i
], APPLESMC_DATA_PORT
);
287 if (__wait_status(0x04))
291 outb(len
, APPLESMC_DATA_PORT
);
293 for (i
= 0; i
< len
; i
++) {
294 if (__wait_status(0x04))
296 outb(buffer
[i
], APPLESMC_DATA_PORT
);
303 * applesmc_get_key_at_index - get key at index, and put the result in key
304 * (char[6]). Returns zero on success or a negative error on failure. Callers
305 * must hold applesmc_lock.
307 static int applesmc_get_key_at_index(int index
, char* key
)
311 readkey
[0] = index
>> 24;
312 readkey
[1] = index
>> 16;
313 readkey
[2] = index
>> 8;
316 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD
))
319 for (i
= 0; i
< 4; i
++) {
320 outb(readkey
[i
], APPLESMC_DATA_PORT
);
321 if (__wait_status(0x04))
325 outb(4, APPLESMC_DATA_PORT
);
327 for (i
= 0; i
< 4; i
++) {
328 if (__wait_status(0x05))
330 key
[i
] = inb(APPLESMC_DATA_PORT
);
338 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
339 * Returns zero on success or a negative error on failure. Callers must
340 * hold applesmc_lock.
342 static int applesmc_get_key_type(char* key
, char* type
)
346 if (send_command(APPLESMC_GET_KEY_TYPE_CMD
))
349 for (i
= 0; i
< 4; i
++) {
350 outb(key
[i
], APPLESMC_DATA_PORT
);
351 if (__wait_status(0x04))
355 outb(6, APPLESMC_DATA_PORT
);
357 for (i
= 0; i
< 6; i
++) {
358 if (__wait_status(0x05))
360 type
[i
] = inb(APPLESMC_DATA_PORT
);
368 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
369 * hold applesmc_lock.
371 static int applesmc_read_motion_sensor(int index
, s16
* value
)
378 ret
= applesmc_read_key(MOTION_SENSOR_X_KEY
, buffer
, 2);
381 ret
= applesmc_read_key(MOTION_SENSOR_Y_KEY
, buffer
, 2);
384 ret
= applesmc_read_key(MOTION_SENSOR_Z_KEY
, buffer
, 2);
390 *value
= ((s16
)buffer
[0] << 8) | buffer
[1];
396 * applesmc_device_init - initialize the accelerometer. Returns zero on success
397 * and negative error code on failure. Can sleep.
399 static int applesmc_device_init(void)
401 int total
, ret
= -ENXIO
;
404 if (!applesmc_accelerometer
)
407 mutex_lock(&applesmc_lock
);
409 for (total
= INIT_TIMEOUT_MSECS
; total
> 0; total
-= INIT_WAIT_MSECS
) {
411 printk(KERN_DEBUG
"applesmc try %d\n", total
);
412 if (!applesmc_read_key(MOTION_SENSOR_KEY
, buffer
, 2) &&
413 (buffer
[0] != 0x00 || buffer
[1] != 0x00)) {
414 if (total
== INIT_TIMEOUT_MSECS
) {
415 printk(KERN_DEBUG
"applesmc: device has"
416 " already been initialized"
417 " (0x%02x, 0x%02x).\n",
418 buffer
[0], buffer
[1]);
420 printk(KERN_DEBUG
"applesmc: device"
421 " successfully initialized"
422 " (0x%02x, 0x%02x).\n",
423 buffer
[0], buffer
[1]);
430 applesmc_write_key(MOTION_SENSOR_KEY
, buffer
, 2);
431 msleep(INIT_WAIT_MSECS
);
434 printk(KERN_WARNING
"applesmc: failed to init the device\n");
437 mutex_unlock(&applesmc_lock
);
442 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
445 static int applesmc_get_fan_count(void)
450 mutex_lock(&applesmc_lock
);
452 ret
= applesmc_read_key(FANS_COUNT
, buffer
, 1);
454 mutex_unlock(&applesmc_lock
);
461 /* Device model stuff */
462 static int applesmc_probe(struct platform_device
*dev
)
466 ret
= applesmc_device_init();
470 printk(KERN_INFO
"applesmc: device successfully initialized.\n");
474 static int applesmc_resume(struct platform_device
*dev
)
476 return applesmc_device_init();
479 static struct platform_driver applesmc_driver
= {
480 .probe
= applesmc_probe
,
481 .resume
= applesmc_resume
,
484 .owner
= THIS_MODULE
,
489 * applesmc_calibrate - Set our "resting" values. Callers must
490 * hold applesmc_lock.
492 static void applesmc_calibrate(void)
494 applesmc_read_motion_sensor(SENSOR_X
, &rest_x
);
495 applesmc_read_motion_sensor(SENSOR_Y
, &rest_y
);
499 static void applesmc_idev_poll(struct input_polled_dev
*dev
)
501 struct input_dev
*idev
= dev
->input
;
504 mutex_lock(&applesmc_lock
);
506 if (applesmc_read_motion_sensor(SENSOR_X
, &x
))
508 if (applesmc_read_motion_sensor(SENSOR_Y
, &y
))
512 input_report_abs(idev
, ABS_X
, x
- rest_x
);
513 input_report_abs(idev
, ABS_Y
, y
- rest_y
);
517 mutex_unlock(&applesmc_lock
);
522 static ssize_t
applesmc_name_show(struct device
*dev
,
523 struct device_attribute
*attr
, char *buf
)
525 return snprintf(buf
, PAGE_SIZE
, "applesmc\n");
528 static ssize_t
applesmc_position_show(struct device
*dev
,
529 struct device_attribute
*attr
, char *buf
)
534 mutex_lock(&applesmc_lock
);
536 ret
= applesmc_read_motion_sensor(SENSOR_X
, &x
);
539 ret
= applesmc_read_motion_sensor(SENSOR_Y
, &y
);
542 ret
= applesmc_read_motion_sensor(SENSOR_Z
, &z
);
547 mutex_unlock(&applesmc_lock
);
551 return snprintf(buf
, PAGE_SIZE
, "(%d,%d,%d)\n", x
, y
, z
);
554 static ssize_t
applesmc_light_show(struct device
*dev
,
555 struct device_attribute
*attr
, char *sysfsbuf
)
557 static int data_length
;
559 u8 left
= 0, right
= 0;
560 u8 buffer
[10], query
[6];
562 mutex_lock(&applesmc_lock
);
565 ret
= applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY
, query
);
568 data_length
= clamp_val(query
[0], 0, 10);
569 printk(KERN_INFO
"applesmc: light sensor data length set to "
570 "%d\n", data_length
);
573 ret
= applesmc_read_key(LIGHT_SENSOR_LEFT_KEY
, buffer
, data_length
);
577 ret
= applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY
, buffer
, data_length
);
581 mutex_unlock(&applesmc_lock
);
585 return snprintf(sysfsbuf
, PAGE_SIZE
, "(%d,%d)\n", left
, right
);
588 /* Displays degree Celsius * 1000 */
589 static ssize_t
applesmc_show_temperature(struct device
*dev
,
590 struct device_attribute
*devattr
, char *sysfsbuf
)
595 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
597 temperature_sensors_sets
[applesmc_temperature_set
][attr
->index
];
599 mutex_lock(&applesmc_lock
);
601 ret
= applesmc_read_key(key
, buffer
, 2);
602 temp
= buffer
[0]*1000;
603 temp
+= (buffer
[1] >> 6) * 250;
605 mutex_unlock(&applesmc_lock
);
610 return snprintf(sysfsbuf
, PAGE_SIZE
, "%u\n", temp
);
613 static ssize_t
applesmc_show_fan_speed(struct device
*dev
,
614 struct device_attribute
*attr
, char *sysfsbuf
)
617 unsigned int speed
= 0;
620 struct sensor_device_attribute_2
*sensor_attr
=
621 to_sensor_dev_attr_2(attr
);
623 newkey
[0] = fan_speed_keys
[sensor_attr
->nr
][0];
624 newkey
[1] = '0' + sensor_attr
->index
;
625 newkey
[2] = fan_speed_keys
[sensor_attr
->nr
][2];
626 newkey
[3] = fan_speed_keys
[sensor_attr
->nr
][3];
629 mutex_lock(&applesmc_lock
);
631 ret
= applesmc_read_key(newkey
, buffer
, 2);
632 speed
= ((buffer
[0] << 8 | buffer
[1]) >> 2);
634 mutex_unlock(&applesmc_lock
);
638 return snprintf(sysfsbuf
, PAGE_SIZE
, "%u\n", speed
);
641 static ssize_t
applesmc_store_fan_speed(struct device
*dev
,
642 struct device_attribute
*attr
,
643 const char *sysfsbuf
, size_t count
)
649 struct sensor_device_attribute_2
*sensor_attr
=
650 to_sensor_dev_attr_2(attr
);
652 speed
= simple_strtoul(sysfsbuf
, NULL
, 10);
654 if (speed
> 0x4000) /* Bigger than a 14-bit value */
657 newkey
[0] = fan_speed_keys
[sensor_attr
->nr
][0];
658 newkey
[1] = '0' + sensor_attr
->index
;
659 newkey
[2] = fan_speed_keys
[sensor_attr
->nr
][2];
660 newkey
[3] = fan_speed_keys
[sensor_attr
->nr
][3];
663 mutex_lock(&applesmc_lock
);
665 buffer
[0] = (speed
>> 6) & 0xff;
666 buffer
[1] = (speed
<< 2) & 0xff;
667 ret
= applesmc_write_key(newkey
, buffer
, 2);
669 mutex_unlock(&applesmc_lock
);
676 static ssize_t
applesmc_show_fan_manual(struct device
*dev
,
677 struct device_attribute
*devattr
, char *sysfsbuf
)
682 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
684 mutex_lock(&applesmc_lock
);
686 ret
= applesmc_read_key(FANS_MANUAL
, buffer
, 2);
687 manual
= ((buffer
[0] << 8 | buffer
[1]) >> attr
->index
) & 0x01;
689 mutex_unlock(&applesmc_lock
);
693 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", manual
);
696 static ssize_t
applesmc_store_fan_manual(struct device
*dev
,
697 struct device_attribute
*devattr
,
698 const char *sysfsbuf
, size_t count
)
704 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
706 input
= simple_strtoul(sysfsbuf
, NULL
, 10);
708 mutex_lock(&applesmc_lock
);
710 ret
= applesmc_read_key(FANS_MANUAL
, buffer
, 2);
711 val
= (buffer
[0] << 8 | buffer
[1]);
716 val
= val
| (0x01 << attr
->index
);
718 val
= val
& ~(0x01 << attr
->index
);
720 buffer
[0] = (val
>> 8) & 0xFF;
721 buffer
[1] = val
& 0xFF;
723 ret
= applesmc_write_key(FANS_MANUAL
, buffer
, 2);
726 mutex_unlock(&applesmc_lock
);
733 static ssize_t
applesmc_show_fan_position(struct device
*dev
,
734 struct device_attribute
*attr
, char *sysfsbuf
)
739 struct sensor_device_attribute_2
*sensor_attr
=
740 to_sensor_dev_attr_2(attr
);
742 newkey
[0] = FAN_POSITION
[0];
743 newkey
[1] = '0' + sensor_attr
->index
;
744 newkey
[2] = FAN_POSITION
[2];
745 newkey
[3] = FAN_POSITION
[3];
748 mutex_lock(&applesmc_lock
);
750 ret
= applesmc_read_key(newkey
, buffer
, 16);
753 mutex_unlock(&applesmc_lock
);
757 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", buffer
+4);
760 static ssize_t
applesmc_calibrate_show(struct device
*dev
,
761 struct device_attribute
*attr
, char *sysfsbuf
)
763 return snprintf(sysfsbuf
, PAGE_SIZE
, "(%d,%d)\n", rest_x
, rest_y
);
766 static ssize_t
applesmc_calibrate_store(struct device
*dev
,
767 struct device_attribute
*attr
, const char *sysfsbuf
, size_t count
)
769 mutex_lock(&applesmc_lock
);
770 applesmc_calibrate();
771 mutex_unlock(&applesmc_lock
);
776 /* Store the next backlight value to be written by the work */
777 static unsigned int backlight_value
;
779 static void applesmc_backlight_set(struct work_struct
*work
)
783 mutex_lock(&applesmc_lock
);
784 buffer
[0] = backlight_value
;
786 applesmc_write_key(BACKLIGHT_KEY
, buffer
, 2);
787 mutex_unlock(&applesmc_lock
);
789 static DECLARE_WORK(backlight_work
, &applesmc_backlight_set
);
791 static void applesmc_brightness_set(struct led_classdev
*led_cdev
,
792 enum led_brightness value
)
796 backlight_value
= value
;
797 ret
= queue_work(applesmc_led_wq
, &backlight_work
);
800 printk(KERN_DEBUG
"applesmc: work was already on the queue.\n");
803 static ssize_t
applesmc_key_count_show(struct device
*dev
,
804 struct device_attribute
*attr
, char *sysfsbuf
)
810 mutex_lock(&applesmc_lock
);
812 ret
= applesmc_read_key(KEY_COUNT_KEY
, buffer
, 4);
813 count
= ((u32
)buffer
[0]<<24) + ((u32
)buffer
[1]<<16) +
814 ((u32
)buffer
[2]<<8) + buffer
[3];
816 mutex_unlock(&applesmc_lock
);
820 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", count
);
823 static ssize_t
applesmc_key_at_index_read_show(struct device
*dev
,
824 struct device_attribute
*attr
, char *sysfsbuf
)
830 mutex_lock(&applesmc_lock
);
832 ret
= applesmc_get_key_at_index(key_at_index
, key
);
834 if (ret
|| !key
[0]) {
835 mutex_unlock(&applesmc_lock
);
840 ret
= applesmc_get_key_type(key
, info
);
843 mutex_unlock(&applesmc_lock
);
849 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
850 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
852 ret
= applesmc_read_key(key
, sysfsbuf
, info
[0]);
854 mutex_unlock(&applesmc_lock
);
863 static ssize_t
applesmc_key_at_index_data_length_show(struct device
*dev
,
864 struct device_attribute
*attr
, char *sysfsbuf
)
870 mutex_lock(&applesmc_lock
);
872 ret
= applesmc_get_key_at_index(key_at_index
, key
);
874 if (ret
|| !key
[0]) {
875 mutex_unlock(&applesmc_lock
);
880 ret
= applesmc_get_key_type(key
, info
);
882 mutex_unlock(&applesmc_lock
);
885 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", info
[0]);
890 static ssize_t
applesmc_key_at_index_type_show(struct device
*dev
,
891 struct device_attribute
*attr
, char *sysfsbuf
)
897 mutex_lock(&applesmc_lock
);
899 ret
= applesmc_get_key_at_index(key_at_index
, key
);
901 if (ret
|| !key
[0]) {
902 mutex_unlock(&applesmc_lock
);
907 ret
= applesmc_get_key_type(key
, info
);
909 mutex_unlock(&applesmc_lock
);
912 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", info
+1);
917 static ssize_t
applesmc_key_at_index_name_show(struct device
*dev
,
918 struct device_attribute
*attr
, char *sysfsbuf
)
923 mutex_lock(&applesmc_lock
);
925 ret
= applesmc_get_key_at_index(key_at_index
, key
);
927 mutex_unlock(&applesmc_lock
);
930 return snprintf(sysfsbuf
, PAGE_SIZE
, "%s\n", key
);
935 static ssize_t
applesmc_key_at_index_show(struct device
*dev
,
936 struct device_attribute
*attr
, char *sysfsbuf
)
938 return snprintf(sysfsbuf
, PAGE_SIZE
, "%d\n", key_at_index
);
941 static ssize_t
applesmc_key_at_index_store(struct device
*dev
,
942 struct device_attribute
*attr
, const char *sysfsbuf
, size_t count
)
944 mutex_lock(&applesmc_lock
);
946 key_at_index
= simple_strtoul(sysfsbuf
, NULL
, 10);
948 mutex_unlock(&applesmc_lock
);
953 static struct led_classdev applesmc_backlight
= {
954 .name
= "smc::kbd_backlight",
955 .default_trigger
= "nand-disk",
956 .brightness_set
= applesmc_brightness_set
,
959 static DEVICE_ATTR(name
, 0444, applesmc_name_show
, NULL
);
961 static DEVICE_ATTR(position
, 0444, applesmc_position_show
, NULL
);
962 static DEVICE_ATTR(calibrate
, 0644,
963 applesmc_calibrate_show
, applesmc_calibrate_store
);
965 static struct attribute
*accelerometer_attributes
[] = {
966 &dev_attr_position
.attr
,
967 &dev_attr_calibrate
.attr
,
971 static const struct attribute_group accelerometer_attributes_group
=
972 { .attrs
= accelerometer_attributes
};
974 static DEVICE_ATTR(light
, 0444, applesmc_light_show
, NULL
);
976 static DEVICE_ATTR(key_count
, 0444, applesmc_key_count_show
, NULL
);
977 static DEVICE_ATTR(key_at_index
, 0644,
978 applesmc_key_at_index_show
, applesmc_key_at_index_store
);
979 static DEVICE_ATTR(key_at_index_name
, 0444,
980 applesmc_key_at_index_name_show
, NULL
);
981 static DEVICE_ATTR(key_at_index_type
, 0444,
982 applesmc_key_at_index_type_show
, NULL
);
983 static DEVICE_ATTR(key_at_index_data_length
, 0444,
984 applesmc_key_at_index_data_length_show
, NULL
);
985 static DEVICE_ATTR(key_at_index_data
, 0444,
986 applesmc_key_at_index_read_show
, NULL
);
988 static struct attribute
*key_enumeration_attributes
[] = {
989 &dev_attr_key_count
.attr
,
990 &dev_attr_key_at_index
.attr
,
991 &dev_attr_key_at_index_name
.attr
,
992 &dev_attr_key_at_index_type
.attr
,
993 &dev_attr_key_at_index_data_length
.attr
,
994 &dev_attr_key_at_index_data
.attr
,
998 static const struct attribute_group key_enumeration_group
=
999 { .attrs
= key_enumeration_attributes
};
1002 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1003 * - show actual speed
1004 * - show/store minimum speed
1005 * - show maximum speed
1007 * - show/store target speed
1008 * - show/store manual mode
1010 #define sysfs_fan_speeds_offset(offset) \
1011 static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1012 applesmc_show_fan_speed, NULL, 0, offset-1); \
1014 static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1015 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1017 static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1018 applesmc_show_fan_speed, NULL, 2, offset-1); \
1020 static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1021 applesmc_show_fan_speed, NULL, 3, offset-1); \
1023 static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1024 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1026 static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1027 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1029 static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1030 applesmc_show_fan_position, NULL, offset-1); \
1032 static struct attribute *fan##offset##_attributes[] = { \
1033 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1034 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1035 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1036 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1037 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1038 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1039 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1044 * Create the needed functions for each fan using the macro defined above
1045 * (4 fans are supported)
1047 sysfs_fan_speeds_offset(1);
1048 sysfs_fan_speeds_offset(2);
1049 sysfs_fan_speeds_offset(3);
1050 sysfs_fan_speeds_offset(4);
1052 static const struct attribute_group fan_attribute_groups
[] = {
1053 { .attrs
= fan1_attributes
},
1054 { .attrs
= fan2_attributes
},
1055 { .attrs
= fan3_attributes
},
1056 { .attrs
= fan4_attributes
},
1060 * Temperature sensors sysfs entries.
1062 static SENSOR_DEVICE_ATTR(temp1_input
, S_IRUGO
,
1063 applesmc_show_temperature
, NULL
, 0);
1064 static SENSOR_DEVICE_ATTR(temp2_input
, S_IRUGO
,
1065 applesmc_show_temperature
, NULL
, 1);
1066 static SENSOR_DEVICE_ATTR(temp3_input
, S_IRUGO
,
1067 applesmc_show_temperature
, NULL
, 2);
1068 static SENSOR_DEVICE_ATTR(temp4_input
, S_IRUGO
,
1069 applesmc_show_temperature
, NULL
, 3);
1070 static SENSOR_DEVICE_ATTR(temp5_input
, S_IRUGO
,
1071 applesmc_show_temperature
, NULL
, 4);
1072 static SENSOR_DEVICE_ATTR(temp6_input
, S_IRUGO
,
1073 applesmc_show_temperature
, NULL
, 5);
1074 static SENSOR_DEVICE_ATTR(temp7_input
, S_IRUGO
,
1075 applesmc_show_temperature
, NULL
, 6);
1076 static SENSOR_DEVICE_ATTR(temp8_input
, S_IRUGO
,
1077 applesmc_show_temperature
, NULL
, 7);
1078 static SENSOR_DEVICE_ATTR(temp9_input
, S_IRUGO
,
1079 applesmc_show_temperature
, NULL
, 8);
1080 static SENSOR_DEVICE_ATTR(temp10_input
, S_IRUGO
,
1081 applesmc_show_temperature
, NULL
, 9);
1082 static SENSOR_DEVICE_ATTR(temp11_input
, S_IRUGO
,
1083 applesmc_show_temperature
, NULL
, 10);
1084 static SENSOR_DEVICE_ATTR(temp12_input
, S_IRUGO
,
1085 applesmc_show_temperature
, NULL
, 11);
1086 static SENSOR_DEVICE_ATTR(temp13_input
, S_IRUGO
,
1087 applesmc_show_temperature
, NULL
, 12);
1088 static SENSOR_DEVICE_ATTR(temp14_input
, S_IRUGO
,
1089 applesmc_show_temperature
, NULL
, 13);
1090 static SENSOR_DEVICE_ATTR(temp15_input
, S_IRUGO
,
1091 applesmc_show_temperature
, NULL
, 14);
1092 static SENSOR_DEVICE_ATTR(temp16_input
, S_IRUGO
,
1093 applesmc_show_temperature
, NULL
, 15);
1094 static SENSOR_DEVICE_ATTR(temp17_input
, S_IRUGO
,
1095 applesmc_show_temperature
, NULL
, 16);
1096 static SENSOR_DEVICE_ATTR(temp18_input
, S_IRUGO
,
1097 applesmc_show_temperature
, NULL
, 17);
1098 static SENSOR_DEVICE_ATTR(temp19_input
, S_IRUGO
,
1099 applesmc_show_temperature
, NULL
, 18);
1100 static SENSOR_DEVICE_ATTR(temp20_input
, S_IRUGO
,
1101 applesmc_show_temperature
, NULL
, 19);
1102 static SENSOR_DEVICE_ATTR(temp21_input
, S_IRUGO
,
1103 applesmc_show_temperature
, NULL
, 20);
1104 static SENSOR_DEVICE_ATTR(temp22_input
, S_IRUGO
,
1105 applesmc_show_temperature
, NULL
, 21);
1106 static SENSOR_DEVICE_ATTR(temp23_input
, S_IRUGO
,
1107 applesmc_show_temperature
, NULL
, 22);
1108 static SENSOR_DEVICE_ATTR(temp24_input
, S_IRUGO
,
1109 applesmc_show_temperature
, NULL
, 23);
1110 static SENSOR_DEVICE_ATTR(temp25_input
, S_IRUGO
,
1111 applesmc_show_temperature
, NULL
, 24);
1112 static SENSOR_DEVICE_ATTR(temp26_input
, S_IRUGO
,
1113 applesmc_show_temperature
, NULL
, 25);
1114 static SENSOR_DEVICE_ATTR(temp27_input
, S_IRUGO
,
1115 applesmc_show_temperature
, NULL
, 26);
1116 static SENSOR_DEVICE_ATTR(temp28_input
, S_IRUGO
,
1117 applesmc_show_temperature
, NULL
, 27);
1118 static SENSOR_DEVICE_ATTR(temp29_input
, S_IRUGO
,
1119 applesmc_show_temperature
, NULL
, 28);
1120 static SENSOR_DEVICE_ATTR(temp30_input
, S_IRUGO
,
1121 applesmc_show_temperature
, NULL
, 29);
1122 static SENSOR_DEVICE_ATTR(temp31_input
, S_IRUGO
,
1123 applesmc_show_temperature
, NULL
, 30);
1124 static SENSOR_DEVICE_ATTR(temp32_input
, S_IRUGO
,
1125 applesmc_show_temperature
, NULL
, 31);
1126 static SENSOR_DEVICE_ATTR(temp33_input
, S_IRUGO
,
1127 applesmc_show_temperature
, NULL
, 32);
1128 static SENSOR_DEVICE_ATTR(temp34_input
, S_IRUGO
,
1129 applesmc_show_temperature
, NULL
, 33);
1130 static SENSOR_DEVICE_ATTR(temp35_input
, S_IRUGO
,
1131 applesmc_show_temperature
, NULL
, 34);
1133 static struct attribute
*temperature_attributes
[] = {
1134 &sensor_dev_attr_temp1_input
.dev_attr
.attr
,
1135 &sensor_dev_attr_temp2_input
.dev_attr
.attr
,
1136 &sensor_dev_attr_temp3_input
.dev_attr
.attr
,
1137 &sensor_dev_attr_temp4_input
.dev_attr
.attr
,
1138 &sensor_dev_attr_temp5_input
.dev_attr
.attr
,
1139 &sensor_dev_attr_temp6_input
.dev_attr
.attr
,
1140 &sensor_dev_attr_temp7_input
.dev_attr
.attr
,
1141 &sensor_dev_attr_temp8_input
.dev_attr
.attr
,
1142 &sensor_dev_attr_temp9_input
.dev_attr
.attr
,
1143 &sensor_dev_attr_temp10_input
.dev_attr
.attr
,
1144 &sensor_dev_attr_temp11_input
.dev_attr
.attr
,
1145 &sensor_dev_attr_temp12_input
.dev_attr
.attr
,
1146 &sensor_dev_attr_temp13_input
.dev_attr
.attr
,
1147 &sensor_dev_attr_temp14_input
.dev_attr
.attr
,
1148 &sensor_dev_attr_temp15_input
.dev_attr
.attr
,
1149 &sensor_dev_attr_temp16_input
.dev_attr
.attr
,
1150 &sensor_dev_attr_temp17_input
.dev_attr
.attr
,
1151 &sensor_dev_attr_temp18_input
.dev_attr
.attr
,
1152 &sensor_dev_attr_temp19_input
.dev_attr
.attr
,
1153 &sensor_dev_attr_temp20_input
.dev_attr
.attr
,
1154 &sensor_dev_attr_temp21_input
.dev_attr
.attr
,
1155 &sensor_dev_attr_temp22_input
.dev_attr
.attr
,
1156 &sensor_dev_attr_temp23_input
.dev_attr
.attr
,
1157 &sensor_dev_attr_temp24_input
.dev_attr
.attr
,
1158 &sensor_dev_attr_temp25_input
.dev_attr
.attr
,
1159 &sensor_dev_attr_temp26_input
.dev_attr
.attr
,
1160 &sensor_dev_attr_temp27_input
.dev_attr
.attr
,
1161 &sensor_dev_attr_temp28_input
.dev_attr
.attr
,
1162 &sensor_dev_attr_temp29_input
.dev_attr
.attr
,
1163 &sensor_dev_attr_temp30_input
.dev_attr
.attr
,
1164 &sensor_dev_attr_temp31_input
.dev_attr
.attr
,
1165 &sensor_dev_attr_temp32_input
.dev_attr
.attr
,
1166 &sensor_dev_attr_temp33_input
.dev_attr
.attr
,
1167 &sensor_dev_attr_temp34_input
.dev_attr
.attr
,
1168 &sensor_dev_attr_temp35_input
.dev_attr
.attr
,
1172 static const struct attribute_group temperature_attributes_group
=
1173 { .attrs
= temperature_attributes
};
1178 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1180 static int applesmc_dmi_match(const struct dmi_system_id
*id
)
1183 struct dmi_match_data
* dmi_data
= id
->driver_data
;
1184 printk(KERN_INFO
"applesmc: %s detected:\n", id
->ident
);
1185 applesmc_accelerometer
= dmi_data
->accelerometer
;
1186 printk(KERN_INFO
"applesmc: - Model %s accelerometer\n",
1187 applesmc_accelerometer
? "with" : "without");
1188 applesmc_light
= dmi_data
->light
;
1189 printk(KERN_INFO
"applesmc: - Model %s light sensors and backlight\n",
1190 applesmc_light
? "with" : "without");
1192 applesmc_temperature_set
= dmi_data
->temperature_set
;
1193 while (temperature_sensors_sets
[applesmc_temperature_set
][i
] != NULL
)
1195 printk(KERN_INFO
"applesmc: - Model with %d temperature sensors\n", i
);
1199 /* Create accelerometer ressources */
1200 static int applesmc_create_accelerometer(void)
1202 struct input_dev
*idev
;
1205 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1206 &accelerometer_attributes_group
);
1210 applesmc_idev
= input_allocate_polled_device();
1211 if (!applesmc_idev
) {
1216 applesmc_idev
->poll
= applesmc_idev_poll
;
1217 applesmc_idev
->poll_interval
= APPLESMC_POLL_INTERVAL
;
1219 /* initial calibrate for the input device */
1220 applesmc_calibrate();
1222 /* initialize the input device */
1223 idev
= applesmc_idev
->input
;
1224 idev
->name
= "applesmc";
1225 idev
->id
.bustype
= BUS_HOST
;
1226 idev
->dev
.parent
= &pdev
->dev
;
1227 idev
->evbit
[0] = BIT_MASK(EV_ABS
);
1228 input_set_abs_params(idev
, ABS_X
,
1229 -256, 256, APPLESMC_INPUT_FUZZ
, APPLESMC_INPUT_FLAT
);
1230 input_set_abs_params(idev
, ABS_Y
,
1231 -256, 256, APPLESMC_INPUT_FUZZ
, APPLESMC_INPUT_FLAT
);
1233 ret
= input_register_polled_device(applesmc_idev
);
1240 input_free_polled_device(applesmc_idev
);
1243 sysfs_remove_group(&pdev
->dev
.kobj
, &accelerometer_attributes_group
);
1246 printk(KERN_WARNING
"applesmc: driver init failed (ret=%d)!\n", ret
);
1250 /* Release all ressources used by the accelerometer */
1251 static void applesmc_release_accelerometer(void)
1253 input_unregister_polled_device(applesmc_idev
);
1254 input_free_polled_device(applesmc_idev
);
1255 sysfs_remove_group(&pdev
->dev
.kobj
, &accelerometer_attributes_group
);
1258 static __initdata
struct dmi_match_data applesmc_dmi_data
[] = {
1259 /* MacBook Pro: accelerometer, backlight and temperature set 0 */
1260 { .accelerometer
= 1, .light
= 1, .temperature_set
= 0 },
1261 /* MacBook2: accelerometer and temperature set 1 */
1262 { .accelerometer
= 1, .light
= 0, .temperature_set
= 1 },
1263 /* MacBook: accelerometer and temperature set 2 */
1264 { .accelerometer
= 1, .light
= 0, .temperature_set
= 2 },
1265 /* MacMini: temperature set 3 */
1266 { .accelerometer
= 0, .light
= 0, .temperature_set
= 3 },
1267 /* MacPro: temperature set 4 */
1268 { .accelerometer
= 0, .light
= 0, .temperature_set
= 4 },
1269 /* iMac: temperature set 5 */
1270 { .accelerometer
= 0, .light
= 0, .temperature_set
= 5 },
1271 /* MacBook3: accelerometer and temperature set 6 */
1272 { .accelerometer
= 1, .light
= 0, .temperature_set
= 6 },
1273 /* MacBook Air: accelerometer, backlight and temperature set 7 */
1274 { .accelerometer
= 1, .light
= 1, .temperature_set
= 7 },
1275 /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1276 { .accelerometer
= 1, .light
= 1, .temperature_set
= 8 },
1277 /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1278 { .accelerometer
= 1, .light
= 1, .temperature_set
= 9 },
1281 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1282 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1283 static __initdata
struct dmi_system_id applesmc_whitelist
[] = {
1284 { applesmc_dmi_match
, "Apple MacBook Air", {
1285 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1286 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookAir") },
1287 &applesmc_dmi_data
[7]},
1288 { applesmc_dmi_match
, "Apple MacBook Pro 4", {
1289 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1290 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro4") },
1291 &applesmc_dmi_data
[8]},
1292 { applesmc_dmi_match
, "Apple MacBook Pro 3", {
1293 DMI_MATCH(DMI_BOARD_VENDOR
, "Apple"),
1294 DMI_MATCH(DMI_PRODUCT_NAME
, "MacBookPro3") },
1295 &applesmc_dmi_data
[9]},
1296 { applesmc_dmi_match
, "Apple MacBook Pro", {
1297 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1298 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBookPro") },
1299 &applesmc_dmi_data
[0]},
1300 { applesmc_dmi_match
, "Apple MacBook (v2)", {
1301 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1302 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook2") },
1303 &applesmc_dmi_data
[1]},
1304 { applesmc_dmi_match
, "Apple MacBook (v3)", {
1305 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1306 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook3") },
1307 &applesmc_dmi_data
[6]},
1308 { applesmc_dmi_match
, "Apple MacBook", {
1309 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1310 DMI_MATCH(DMI_PRODUCT_NAME
,"MacBook") },
1311 &applesmc_dmi_data
[2]},
1312 { applesmc_dmi_match
, "Apple Macmini", {
1313 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1314 DMI_MATCH(DMI_PRODUCT_NAME
,"Macmini") },
1315 &applesmc_dmi_data
[3]},
1316 { applesmc_dmi_match
, "Apple MacPro2", {
1317 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1318 DMI_MATCH(DMI_PRODUCT_NAME
,"MacPro2") },
1319 &applesmc_dmi_data
[4]},
1320 { applesmc_dmi_match
, "Apple iMac", {
1321 DMI_MATCH(DMI_BOARD_VENDOR
,"Apple"),
1322 DMI_MATCH(DMI_PRODUCT_NAME
,"iMac") },
1323 &applesmc_dmi_data
[5]},
1327 static int __init
applesmc_init(void)
1333 if (!dmi_check_system(applesmc_whitelist
)) {
1334 printk(KERN_WARNING
"applesmc: supported laptop not found!\n");
1339 if (!request_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
,
1345 ret
= platform_driver_register(&applesmc_driver
);
1349 pdev
= platform_device_register_simple("applesmc", APPLESMC_DATA_PORT
,
1352 ret
= PTR_ERR(pdev
);
1356 ret
= sysfs_create_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1360 /* Create key enumeration sysfs files */
1361 ret
= sysfs_create_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1365 /* create fan files */
1366 count
= applesmc_get_fan_count();
1368 printk(KERN_ERR
"applesmc: Cannot get the number of fans.\n");
1370 printk(KERN_INFO
"applesmc: %d fans found.\n", count
);
1374 printk(KERN_WARNING
"applesmc: More than 4 fans found,"
1375 " but at most 4 fans are supported"
1376 " by the driver.\n");
1378 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1379 &fan_attribute_groups
[3]);
1381 goto out_key_enumeration
;
1383 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1384 &fan_attribute_groups
[2]);
1386 goto out_key_enumeration
;
1388 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1389 &fan_attribute_groups
[1]);
1391 goto out_key_enumeration
;
1393 ret
= sysfs_create_group(&pdev
->dev
.kobj
,
1394 &fan_attribute_groups
[0]);
1403 temperature_sensors_sets
[applesmc_temperature_set
][i
] != NULL
;
1405 if (temperature_attributes
[i
] == NULL
) {
1406 printk(KERN_ERR
"applesmc: More temperature sensors "
1407 "in temperature_sensors_sets (at least %i)"
1408 "than available sysfs files in "
1409 "temperature_attributes (%i), please report "
1410 "this bug.\n", i
, i
-1);
1411 goto out_temperature
;
1413 ret
= sysfs_create_file(&pdev
->dev
.kobj
,
1414 temperature_attributes
[i
]);
1416 goto out_temperature
;
1419 if (applesmc_accelerometer
) {
1420 ret
= applesmc_create_accelerometer();
1422 goto out_temperature
;
1425 if (applesmc_light
) {
1426 /* Add light sensor file */
1427 ret
= sysfs_create_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1429 goto out_accelerometer
;
1431 /* Create the workqueue */
1432 applesmc_led_wq
= create_singlethread_workqueue("applesmc-led");
1433 if (!applesmc_led_wq
) {
1435 goto out_light_sysfs
;
1438 /* register as a led device */
1439 ret
= led_classdev_register(&pdev
->dev
, &applesmc_backlight
);
1444 hwmon_dev
= hwmon_device_register(&pdev
->dev
);
1445 if (IS_ERR(hwmon_dev
)) {
1446 ret
= PTR_ERR(hwmon_dev
);
1447 goto out_light_ledclass
;
1450 printk(KERN_INFO
"applesmc: driver successfully loaded.\n");
1456 led_classdev_unregister(&applesmc_backlight
);
1459 destroy_workqueue(applesmc_led_wq
);
1462 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1464 if (applesmc_accelerometer
)
1465 applesmc_release_accelerometer();
1467 sysfs_remove_group(&pdev
->dev
.kobj
, &temperature_attributes_group
);
1468 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[0]);
1470 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[1]);
1471 out_key_enumeration
:
1472 sysfs_remove_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1474 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1476 platform_device_unregister(pdev
);
1478 platform_driver_unregister(&applesmc_driver
);
1480 release_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
);
1482 printk(KERN_WARNING
"applesmc: driver init failed (ret=%d)!\n", ret
);
1486 static void __exit
applesmc_exit(void)
1488 hwmon_device_unregister(hwmon_dev
);
1489 if (applesmc_light
) {
1490 led_classdev_unregister(&applesmc_backlight
);
1491 destroy_workqueue(applesmc_led_wq
);
1492 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_light
.attr
);
1494 if (applesmc_accelerometer
)
1495 applesmc_release_accelerometer();
1496 sysfs_remove_group(&pdev
->dev
.kobj
, &temperature_attributes_group
);
1497 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[0]);
1498 sysfs_remove_group(&pdev
->dev
.kobj
, &fan_attribute_groups
[1]);
1499 sysfs_remove_group(&pdev
->dev
.kobj
, &key_enumeration_group
);
1500 sysfs_remove_file(&pdev
->dev
.kobj
, &dev_attr_name
.attr
);
1501 platform_device_unregister(pdev
);
1502 platform_driver_unregister(&applesmc_driver
);
1503 release_region(APPLESMC_DATA_PORT
, APPLESMC_NR_PORTS
);
1505 printk(KERN_INFO
"applesmc: driver unloaded.\n");
1508 module_init(applesmc_init
);
1509 module_exit(applesmc_exit
);
1511 MODULE_AUTHOR("Nicolas Boichat");
1512 MODULE_DESCRIPTION("Apple SMC");
1513 MODULE_LICENSE("GPL v2");