Parport driver: disable pc-style parport on Blackfin systems
[deliverable/linux.git] / drivers / hwmon / applesmc.c
CommitLineData
6f2fad74
NB
1/*
2 * drivers/hwmon/applesmc.c - driver for Apple's SMC (accelerometer, temperature
3 * sensors, fan control, keyboard backlight control) used in Intel-based Apple
4 * computers.
5 *
6 * Copyright (C) 2007 Nicolas Boichat <nicolas@boichat.ch>
7 *
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>
11 *
12 * Fan control based on smcFanControl:
13 * Copyright (C) 2006 Hendrik Holtmann <holtmann@mac.com>
14 *
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.
18 *
19 * This program is distributed in the hope that it will be useful, but WITHOUT
20 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
22 * more details.
23 *
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
27 */
28
29#include <linux/delay.h>
30#include <linux/platform_device.h>
d5cf2b99 31#include <linux/input-polldev.h>
6f2fad74
NB
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/timer.h>
35#include <linux/dmi.h>
36#include <linux/mutex.h>
37#include <linux/hwmon-sysfs.h>
38#include <asm/io.h>
39#include <linux/leds.h>
40#include <linux/hwmon.h>
41#include <linux/workqueue.h>
42
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
47
48#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
49
50#define APPLESMC_MAX_DATA_LENGTH 32
51
8c9398d1
HR
52#define APPLESMC_MIN_WAIT 0x0040
53#define APPLESMC_MAX_WAIT 0x8000
54
6f2fad74
NB
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
60
61#define KEY_COUNT_KEY "#KEY" /* r-o ui32 */
62
8bd1a12a
HR
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) */
d5cf2b99 65#define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */
6f2fad74 66
d5cf2b99 67#define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */
6f2fad74
NB
68
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 */
73
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] */
82
83/*
84 * Temperature sensors keys (sp78 - 2 bytes).
6f2fad74 85 */
8de57709 86static const char* temperature_sensors_sets[][36] = {
1bed24b9 87/* Set 0: Macbook Pro */
6f2fad74
NB
88 { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
89 "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
cd19ba13
RO
90/* Set 1: Macbook2 set */
91 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "TTF0", "Th0H",
92 "Th0S", "Th1H", NULL },
93/* Set 2: Macbook set */
1bed24b9
MS
94 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S",
95 "Th1H", "Ts0P", NULL },
cd19ba13 96/* Set 3: Macmini set */
8de57709 97 { "TC0D", "TC0P", NULL },
cd19ba13 98/* Set 4: Mac Pro (2 x Quad-Core) */
8de57709
RR
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 },
9f86f28d
RDI
104/* Set 5: iMac */
105 { "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P",
106 "Tp0C", NULL },
f91a79fe
GS
107/* Set 6: Macbook3 set */
108 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H",
109 "Th0S", "Th1H", NULL },
f5274c97
HR
110/* Set 7: Macbook Air */
111 { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TC0P", "TCFP",
112 "TTF0", "TW0P", "Th0H", "Tp0P", "TpFP", "Ts0P", "Ts0S", NULL },
d7549905
HR
113/* Set 8: Macbook Pro 4,1 (Penryn) */
114 { "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", "Th0H",
115 "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
07e8dbd3
HR
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 },
6e3530fa
HR
119/* Set 10: iMac 5,1 */
120 { "TA0P", "TC0D", "TC0P", "TG0D", "TH0P", "TO0P", "Tm0P", NULL },
181209a1
HR
121/* Set 11: Macbook 5,1 */
122 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0P", "TN0D", "TN0P",
123 "TTF0", "Th0H", "Th1H", "ThFH", "Ts0P", "Ts0S", NULL },
a6660325
HR
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 },
eefc488f
HR
128/* Set 13: iMac 8,1 */
129 { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P",
130 "TL0P", "TO0P", "TW0P", "Tm0P", "Tp0P", NULL },
6f2fad74
NB
131};
132
133/* List of keys used to read/write fan speeds */
134static const char* fan_speed_keys[] = {
135 FAN_ACTUAL_SPEED,
136 FAN_MIN_SPEED,
137 FAN_MAX_SPEED,
138 FAN_SAFE_SPEED,
139 FAN_TARGET_SPEED
140};
141
142#define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
143#define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
144
d5cf2b99 145#define APPLESMC_POLL_INTERVAL 50 /* msecs */
6f2fad74
NB
146#define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
147#define APPLESMC_INPUT_FLAT 4
148
149#define SENSOR_X 0
150#define SENSOR_Y 1
151#define SENSOR_Z 2
152
153/* Structure to be passed to DMI_MATCH function */
154struct dmi_match_data {
155/* Indicates whether this computer has an accelerometer. */
156 int accelerometer;
157/* Indicates whether this computer has light sensors and keyboard backlight. */
158 int light;
159/* Indicates which temperature sensors set to use. */
160 int temperature_set;
161};
162
163static const int debug;
164static struct platform_device *pdev;
165static s16 rest_x;
166static s16 rest_y;
1beeffe4 167static struct device *hwmon_dev;
d5cf2b99 168static struct input_polled_dev *applesmc_idev;
6f2fad74
NB
169
170/* Indicates whether this computer has an accelerometer. */
171static unsigned int applesmc_accelerometer;
172
173/* Indicates whether this computer has light sensors and keyboard backlight. */
174static unsigned int applesmc_light;
175
176/* Indicates which temperature sensors set to use. */
177static unsigned int applesmc_temperature_set;
178
d5cf2b99 179static DEFINE_MUTEX(applesmc_lock);
6f2fad74
NB
180
181/*
182 * Last index written to key_at_index sysfs file, and value to use for all other
183 * key_at_index_* sysfs files.
184 */
185static unsigned int key_at_index;
186
187static struct workqueue_struct *applesmc_led_wq;
188
189/*
8c9398d1 190 * __wait_status - Wait up to 32ms for the status port to get a certain value
6f2fad74
NB
191 * (masked with 0x0f), returning zero if the value is obtained. Callers must
192 * hold applesmc_lock.
193 */
194static int __wait_status(u8 val)
195{
8c9398d1 196 int us;
6f2fad74
NB
197
198 val = val & APPLESMC_STATUS_MASK;
199
8c9398d1
HR
200 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
201 udelay(us);
6f2fad74
NB
202 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
203 if (debug)
204 printk(KERN_DEBUG
8c9398d1
HR
205 "Waited %d us for status %x\n",
206 2 * us - APPLESMC_MIN_WAIT, val);
6f2fad74
NB
207 return 0;
208 }
6f2fad74
NB
209 }
210
211 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
212 val, inb(APPLESMC_CMD_PORT));
213
214 return -EIO;
215}
216
84d2d7f2
HR
217/*
218 * special treatment of command port - on newer macbooks, it seems necessary
219 * to resend the command byte before polling the status again. Callers must
220 * hold applesmc_lock.
221 */
222static int send_command(u8 cmd)
223{
8c9398d1
HR
224 int us;
225 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
84d2d7f2 226 outb(cmd, APPLESMC_CMD_PORT);
8c9398d1 227 udelay(us);
84d2d7f2
HR
228 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
229 return 0;
84d2d7f2
HR
230 }
231 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
232 cmd, inb(APPLESMC_CMD_PORT));
233 return -EIO;
234}
235
6f2fad74
NB
236/*
237 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
238 * Returns zero on success or a negative error on failure. Callers must
239 * hold applesmc_lock.
240 */
241static int applesmc_read_key(const char* key, u8* buffer, u8 len)
242{
243 int i;
244
245 if (len > APPLESMC_MAX_DATA_LENGTH) {
246 printk(KERN_ERR "applesmc_read_key: cannot read more than "
247 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
248 return -EINVAL;
249 }
250
84d2d7f2 251 if (send_command(APPLESMC_READ_CMD))
6f2fad74
NB
252 return -EIO;
253
254 for (i = 0; i < 4; i++) {
255 outb(key[i], APPLESMC_DATA_PORT);
256 if (__wait_status(0x04))
257 return -EIO;
258 }
259 if (debug)
260 printk(KERN_DEBUG "<%s", key);
261
262 outb(len, APPLESMC_DATA_PORT);
263 if (debug)
264 printk(KERN_DEBUG ">%x", len);
265
266 for (i = 0; i < len; i++) {
267 if (__wait_status(0x05))
268 return -EIO;
269 buffer[i] = inb(APPLESMC_DATA_PORT);
270 if (debug)
271 printk(KERN_DEBUG "<%x", buffer[i]);
272 }
273 if (debug)
274 printk(KERN_DEBUG "\n");
275
276 return 0;
277}
278
279/*
280 * applesmc_write_key - writes len bytes from buffer to a given key.
281 * Returns zero on success or a negative error on failure. Callers must
282 * hold applesmc_lock.
283 */
284static int applesmc_write_key(const char* key, u8* buffer, u8 len)
285{
286 int i;
287
288 if (len > APPLESMC_MAX_DATA_LENGTH) {
289 printk(KERN_ERR "applesmc_write_key: cannot write more than "
290 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
291 return -EINVAL;
292 }
293
84d2d7f2 294 if (send_command(APPLESMC_WRITE_CMD))
6f2fad74
NB
295 return -EIO;
296
297 for (i = 0; i < 4; i++) {
298 outb(key[i], APPLESMC_DATA_PORT);
299 if (__wait_status(0x04))
300 return -EIO;
301 }
302
303 outb(len, APPLESMC_DATA_PORT);
304
305 for (i = 0; i < len; i++) {
306 if (__wait_status(0x04))
307 return -EIO;
308 outb(buffer[i], APPLESMC_DATA_PORT);
309 }
310
311 return 0;
312}
313
314/*
315 * applesmc_get_key_at_index - get key at index, and put the result in key
316 * (char[6]). Returns zero on success or a negative error on failure. Callers
317 * must hold applesmc_lock.
318 */
319static int applesmc_get_key_at_index(int index, char* key)
320{
321 int i;
322 u8 readkey[4];
323 readkey[0] = index >> 24;
324 readkey[1] = index >> 16;
325 readkey[2] = index >> 8;
326 readkey[3] = index;
327
84d2d7f2 328 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
6f2fad74
NB
329 return -EIO;
330
331 for (i = 0; i < 4; i++) {
332 outb(readkey[i], APPLESMC_DATA_PORT);
333 if (__wait_status(0x04))
334 return -EIO;
335 }
336
337 outb(4, APPLESMC_DATA_PORT);
338
339 for (i = 0; i < 4; i++) {
340 if (__wait_status(0x05))
341 return -EIO;
342 key[i] = inb(APPLESMC_DATA_PORT);
343 }
344 key[4] = 0;
345
346 return 0;
347}
348
349/*
350 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
351 * Returns zero on success or a negative error on failure. Callers must
352 * hold applesmc_lock.
353 */
354static int applesmc_get_key_type(char* key, char* type)
355{
356 int i;
357
84d2d7f2 358 if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
6f2fad74
NB
359 return -EIO;
360
361 for (i = 0; i < 4; i++) {
362 outb(key[i], APPLESMC_DATA_PORT);
363 if (__wait_status(0x04))
364 return -EIO;
365 }
366
05224091 367 outb(6, APPLESMC_DATA_PORT);
6f2fad74
NB
368
369 for (i = 0; i < 6; i++) {
370 if (__wait_status(0x05))
371 return -EIO;
372 type[i] = inb(APPLESMC_DATA_PORT);
373 }
374 type[5] = 0;
375
376 return 0;
377}
378
379/*
380 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
381 * hold applesmc_lock.
382 */
383static int applesmc_read_motion_sensor(int index, s16* value)
384{
385 u8 buffer[2];
386 int ret;
387
388 switch (index) {
389 case SENSOR_X:
390 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
391 break;
392 case SENSOR_Y:
393 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
394 break;
395 case SENSOR_Z:
396 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
397 break;
398 default:
399 ret = -EINVAL;
400 }
401
402 *value = ((s16)buffer[0] << 8) | buffer[1];
403
404 return ret;
405}
406
407/*
408 * applesmc_device_init - initialize the accelerometer. Returns zero on success
409 * and negative error code on failure. Can sleep.
410 */
411static int applesmc_device_init(void)
412{
413 int total, ret = -ENXIO;
414 u8 buffer[2];
415
416 if (!applesmc_accelerometer)
417 return 0;
418
419 mutex_lock(&applesmc_lock);
420
421 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
422 if (debug)
423 printk(KERN_DEBUG "applesmc try %d\n", total);
424 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
425 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
426 if (total == INIT_TIMEOUT_MSECS) {
427 printk(KERN_DEBUG "applesmc: device has"
428 " already been initialized"
429 " (0x%02x, 0x%02x).\n",
430 buffer[0], buffer[1]);
431 } else {
432 printk(KERN_DEBUG "applesmc: device"
433 " successfully initialized"
434 " (0x%02x, 0x%02x).\n",
435 buffer[0], buffer[1]);
436 }
437 ret = 0;
438 goto out;
439 }
440 buffer[0] = 0xe0;
441 buffer[1] = 0x00;
442 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
443 msleep(INIT_WAIT_MSECS);
444 }
445
446 printk(KERN_WARNING "applesmc: failed to init the device\n");
447
448out:
449 mutex_unlock(&applesmc_lock);
450 return ret;
451}
452
453/*
454 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
455 * applesmc_lock.
456 */
457static int applesmc_get_fan_count(void)
458{
459 int ret;
460 u8 buffer[1];
461
462 mutex_lock(&applesmc_lock);
463
464 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
465
466 mutex_unlock(&applesmc_lock);
467 if (ret)
468 return ret;
469 else
470 return buffer[0];
471}
472
473/* Device model stuff */
474static int applesmc_probe(struct platform_device *dev)
475{
476 int ret;
477
478 ret = applesmc_device_init();
479 if (ret)
480 return ret;
481
482 printk(KERN_INFO "applesmc: device successfully initialized.\n");
483 return 0;
484}
485
486static int applesmc_resume(struct platform_device *dev)
487{
488 return applesmc_device_init();
489}
490
491static struct platform_driver applesmc_driver = {
492 .probe = applesmc_probe,
493 .resume = applesmc_resume,
494 .driver = {
495 .name = "applesmc",
496 .owner = THIS_MODULE,
497 },
498};
499
500/*
501 * applesmc_calibrate - Set our "resting" values. Callers must
502 * hold applesmc_lock.
503 */
504static void applesmc_calibrate(void)
505{
506 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
507 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
508 rest_x = -rest_x;
509}
510
d5cf2b99 511static void applesmc_idev_poll(struct input_polled_dev *dev)
6f2fad74 512{
d5cf2b99 513 struct input_dev *idev = dev->input;
6f2fad74
NB
514 s16 x, y;
515
d5cf2b99 516 mutex_lock(&applesmc_lock);
6f2fad74
NB
517
518 if (applesmc_read_motion_sensor(SENSOR_X, &x))
519 goto out;
520 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
521 goto out;
522
523 x = -x;
d5cf2b99
DT
524 input_report_abs(idev, ABS_X, x - rest_x);
525 input_report_abs(idev, ABS_Y, y - rest_y);
526 input_sync(idev);
6f2fad74
NB
527
528out:
6f2fad74
NB
529 mutex_unlock(&applesmc_lock);
530}
531
532/* Sysfs Files */
533
fa74419b
NB
534static ssize_t applesmc_name_show(struct device *dev,
535 struct device_attribute *attr, char *buf)
536{
537 return snprintf(buf, PAGE_SIZE, "applesmc\n");
538}
539
6f2fad74
NB
540static ssize_t applesmc_position_show(struct device *dev,
541 struct device_attribute *attr, char *buf)
542{
543 int ret;
544 s16 x, y, z;
545
546 mutex_lock(&applesmc_lock);
547
548 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
549 if (ret)
550 goto out;
551 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
552 if (ret)
553 goto out;
554 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
555 if (ret)
556 goto out;
557
558out:
559 mutex_unlock(&applesmc_lock);
560 if (ret)
561 return ret;
562 else
563 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
564}
565
566static ssize_t applesmc_light_show(struct device *dev,
567 struct device_attribute *attr, char *sysfsbuf)
568{
8bd1a12a 569 static int data_length;
6f2fad74
NB
570 int ret;
571 u8 left = 0, right = 0;
8bd1a12a 572 u8 buffer[10], query[6];
6f2fad74
NB
573
574 mutex_lock(&applesmc_lock);
575
8bd1a12a
HR
576 if (!data_length) {
577 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
578 if (ret)
579 goto out;
580 data_length = clamp_val(query[0], 0, 10);
581 printk(KERN_INFO "applesmc: light sensor data length set to "
582 "%d\n", data_length);
583 }
584
585 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
6f2fad74
NB
586 left = buffer[2];
587 if (ret)
588 goto out;
8bd1a12a 589 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
6f2fad74
NB
590 right = buffer[2];
591
592out:
593 mutex_unlock(&applesmc_lock);
594 if (ret)
595 return ret;
596 else
597 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
598}
599
600/* Displays degree Celsius * 1000 */
601static ssize_t applesmc_show_temperature(struct device *dev,
602 struct device_attribute *devattr, char *sysfsbuf)
603{
604 int ret;
605 u8 buffer[2];
606 unsigned int temp;
607 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
608 const char* key =
609 temperature_sensors_sets[applesmc_temperature_set][attr->index];
610
611 mutex_lock(&applesmc_lock);
612
613 ret = applesmc_read_key(key, buffer, 2);
614 temp = buffer[0]*1000;
615 temp += (buffer[1] >> 6) * 250;
616
617 mutex_unlock(&applesmc_lock);
618
619 if (ret)
620 return ret;
621 else
622 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
623}
624
625static ssize_t applesmc_show_fan_speed(struct device *dev,
626 struct device_attribute *attr, char *sysfsbuf)
627{
628 int ret;
629 unsigned int speed = 0;
630 char newkey[5];
631 u8 buffer[2];
632 struct sensor_device_attribute_2 *sensor_attr =
633 to_sensor_dev_attr_2(attr);
634
635 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
636 newkey[1] = '0' + sensor_attr->index;
637 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
638 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
639 newkey[4] = 0;
640
641 mutex_lock(&applesmc_lock);
642
643 ret = applesmc_read_key(newkey, buffer, 2);
644 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
645
646 mutex_unlock(&applesmc_lock);
647 if (ret)
648 return ret;
649 else
650 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
651}
652
653static ssize_t applesmc_store_fan_speed(struct device *dev,
654 struct device_attribute *attr,
655 const char *sysfsbuf, size_t count)
656{
657 int ret;
658 u32 speed;
659 char newkey[5];
660 u8 buffer[2];
661 struct sensor_device_attribute_2 *sensor_attr =
662 to_sensor_dev_attr_2(attr);
663
664 speed = simple_strtoul(sysfsbuf, NULL, 10);
665
666 if (speed > 0x4000) /* Bigger than a 14-bit value */
667 return -EINVAL;
668
669 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
670 newkey[1] = '0' + sensor_attr->index;
671 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
672 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
673 newkey[4] = 0;
674
675 mutex_lock(&applesmc_lock);
676
677 buffer[0] = (speed >> 6) & 0xff;
678 buffer[1] = (speed << 2) & 0xff;
679 ret = applesmc_write_key(newkey, buffer, 2);
680
681 mutex_unlock(&applesmc_lock);
682 if (ret)
683 return ret;
684 else
685 return count;
686}
687
688static ssize_t applesmc_show_fan_manual(struct device *dev,
689 struct device_attribute *devattr, char *sysfsbuf)
690{
691 int ret;
692 u16 manual = 0;
693 u8 buffer[2];
694 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
695
696 mutex_lock(&applesmc_lock);
697
698 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
699 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
700
701 mutex_unlock(&applesmc_lock);
702 if (ret)
703 return ret;
704 else
705 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
706}
707
708static ssize_t applesmc_store_fan_manual(struct device *dev,
709 struct device_attribute *devattr,
710 const char *sysfsbuf, size_t count)
711{
712 int ret;
713 u8 buffer[2];
714 u32 input;
715 u16 val;
716 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
717
718 input = simple_strtoul(sysfsbuf, NULL, 10);
719
720 mutex_lock(&applesmc_lock);
721
722 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
723 val = (buffer[0] << 8 | buffer[1]);
724 if (ret)
725 goto out;
726
727 if (input)
728 val = val | (0x01 << attr->index);
729 else
730 val = val & ~(0x01 << attr->index);
731
732 buffer[0] = (val >> 8) & 0xFF;
733 buffer[1] = val & 0xFF;
734
735 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
736
737out:
738 mutex_unlock(&applesmc_lock);
739 if (ret)
740 return ret;
741 else
742 return count;
743}
744
745static ssize_t applesmc_show_fan_position(struct device *dev,
746 struct device_attribute *attr, char *sysfsbuf)
747{
748 int ret;
749 char newkey[5];
750 u8 buffer[17];
751 struct sensor_device_attribute_2 *sensor_attr =
752 to_sensor_dev_attr_2(attr);
753
754 newkey[0] = FAN_POSITION[0];
755 newkey[1] = '0' + sensor_attr->index;
756 newkey[2] = FAN_POSITION[2];
757 newkey[3] = FAN_POSITION[3];
758 newkey[4] = 0;
759
760 mutex_lock(&applesmc_lock);
761
762 ret = applesmc_read_key(newkey, buffer, 16);
763 buffer[16] = 0;
764
765 mutex_unlock(&applesmc_lock);
766 if (ret)
767 return ret;
768 else
769 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
770}
771
772static ssize_t applesmc_calibrate_show(struct device *dev,
773 struct device_attribute *attr, char *sysfsbuf)
774{
775 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
776}
777
778static ssize_t applesmc_calibrate_store(struct device *dev,
779 struct device_attribute *attr, const char *sysfsbuf, size_t count)
780{
781 mutex_lock(&applesmc_lock);
782 applesmc_calibrate();
783 mutex_unlock(&applesmc_lock);
784
785 return count;
786}
787
788/* Store the next backlight value to be written by the work */
789static unsigned int backlight_value;
790
791static void applesmc_backlight_set(struct work_struct *work)
792{
793 u8 buffer[2];
794
795 mutex_lock(&applesmc_lock);
796 buffer[0] = backlight_value;
797 buffer[1] = 0x00;
798 applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
799 mutex_unlock(&applesmc_lock);
800}
801static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
802
803static void applesmc_brightness_set(struct led_classdev *led_cdev,
804 enum led_brightness value)
805{
806 int ret;
807
808 backlight_value = value;
809 ret = queue_work(applesmc_led_wq, &backlight_work);
810
811 if (debug && (!ret))
812 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
813}
814
815static ssize_t applesmc_key_count_show(struct device *dev,
816 struct device_attribute *attr, char *sysfsbuf)
817{
818 int ret;
819 u8 buffer[4];
820 u32 count;
821
822 mutex_lock(&applesmc_lock);
823
824 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
825 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
826 ((u32)buffer[2]<<8) + buffer[3];
827
828 mutex_unlock(&applesmc_lock);
829 if (ret)
830 return ret;
831 else
832 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
833}
834
835static ssize_t applesmc_key_at_index_read_show(struct device *dev,
836 struct device_attribute *attr, char *sysfsbuf)
837{
838 char key[5];
839 char info[6];
840 int ret;
841
842 mutex_lock(&applesmc_lock);
843
844 ret = applesmc_get_key_at_index(key_at_index, key);
845
846 if (ret || !key[0]) {
847 mutex_unlock(&applesmc_lock);
848
849 return -EINVAL;
850 }
851
852 ret = applesmc_get_key_type(key, info);
853
854 if (ret) {
855 mutex_unlock(&applesmc_lock);
856
857 return ret;
858 }
859
860 /*
861 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
862 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
863 */
864 ret = applesmc_read_key(key, sysfsbuf, info[0]);
865
866 mutex_unlock(&applesmc_lock);
867
868 if (!ret) {
869 return info[0];
d5cf2b99 870 } else {
6f2fad74
NB
871 return ret;
872 }
873}
874
875static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
876 struct device_attribute *attr, char *sysfsbuf)
877{
878 char key[5];
879 char info[6];
880 int ret;
881
882 mutex_lock(&applesmc_lock);
883
884 ret = applesmc_get_key_at_index(key_at_index, key);
885
886 if (ret || !key[0]) {
887 mutex_unlock(&applesmc_lock);
888
889 return -EINVAL;
890 }
891
892 ret = applesmc_get_key_type(key, info);
893
894 mutex_unlock(&applesmc_lock);
895
896 if (!ret)
897 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
898 else
899 return ret;
900}
901
902static ssize_t applesmc_key_at_index_type_show(struct device *dev,
903 struct device_attribute *attr, char *sysfsbuf)
904{
905 char key[5];
906 char info[6];
907 int ret;
908
909 mutex_lock(&applesmc_lock);
910
911 ret = applesmc_get_key_at_index(key_at_index, key);
912
913 if (ret || !key[0]) {
914 mutex_unlock(&applesmc_lock);
915
916 return -EINVAL;
917 }
918
919 ret = applesmc_get_key_type(key, info);
920
921 mutex_unlock(&applesmc_lock);
922
923 if (!ret)
924 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
925 else
926 return ret;
927}
928
929static ssize_t applesmc_key_at_index_name_show(struct device *dev,
930 struct device_attribute *attr, char *sysfsbuf)
931{
932 char key[5];
933 int ret;
934
935 mutex_lock(&applesmc_lock);
936
937 ret = applesmc_get_key_at_index(key_at_index, key);
938
939 mutex_unlock(&applesmc_lock);
940
941 if (!ret && key[0])
942 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
943 else
944 return -EINVAL;
945}
946
947static ssize_t applesmc_key_at_index_show(struct device *dev,
948 struct device_attribute *attr, char *sysfsbuf)
949{
950 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
951}
952
953static ssize_t applesmc_key_at_index_store(struct device *dev,
954 struct device_attribute *attr, const char *sysfsbuf, size_t count)
955{
956 mutex_lock(&applesmc_lock);
957
958 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
959
960 mutex_unlock(&applesmc_lock);
961
962 return count;
963}
964
965static struct led_classdev applesmc_backlight = {
6c152bee 966 .name = "smc::kbd_backlight",
6f2fad74
NB
967 .default_trigger = "nand-disk",
968 .brightness_set = applesmc_brightness_set,
969};
970
fa74419b
NB
971static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
972
6f2fad74
NB
973static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
974static DEVICE_ATTR(calibrate, 0644,
975 applesmc_calibrate_show, applesmc_calibrate_store);
976
977static struct attribute *accelerometer_attributes[] = {
978 &dev_attr_position.attr,
979 &dev_attr_calibrate.attr,
980 NULL
981};
982
983static const struct attribute_group accelerometer_attributes_group =
984 { .attrs = accelerometer_attributes };
985
986static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
987
988static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
989static DEVICE_ATTR(key_at_index, 0644,
990 applesmc_key_at_index_show, applesmc_key_at_index_store);
991static DEVICE_ATTR(key_at_index_name, 0444,
992 applesmc_key_at_index_name_show, NULL);
993static DEVICE_ATTR(key_at_index_type, 0444,
994 applesmc_key_at_index_type_show, NULL);
995static DEVICE_ATTR(key_at_index_data_length, 0444,
996 applesmc_key_at_index_data_length_show, NULL);
997static DEVICE_ATTR(key_at_index_data, 0444,
998 applesmc_key_at_index_read_show, NULL);
999
1000static struct attribute *key_enumeration_attributes[] = {
1001 &dev_attr_key_count.attr,
1002 &dev_attr_key_at_index.attr,
1003 &dev_attr_key_at_index_name.attr,
1004 &dev_attr_key_at_index_type.attr,
1005 &dev_attr_key_at_index_data_length.attr,
1006 &dev_attr_key_at_index_data.attr,
1007 NULL
1008};
1009
1010static const struct attribute_group key_enumeration_group =
1011 { .attrs = key_enumeration_attributes };
1012
1013/*
1014 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1015 * - show actual speed
1016 * - show/store minimum speed
1017 * - show maximum speed
1018 * - show safe speed
1019 * - show/store target speed
1020 * - show/store manual mode
1021 */
1022#define sysfs_fan_speeds_offset(offset) \
1023static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1024 applesmc_show_fan_speed, NULL, 0, offset-1); \
1025\
1026static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1027 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1028\
1029static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1030 applesmc_show_fan_speed, NULL, 2, offset-1); \
1031\
1032static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1033 applesmc_show_fan_speed, NULL, 3, offset-1); \
1034\
1035static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1036 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1037\
1038static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1039 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1040\
da4e8ca3 1041static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
6f2fad74
NB
1042 applesmc_show_fan_position, NULL, offset-1); \
1043\
1044static struct attribute *fan##offset##_attributes[] = { \
1045 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1046 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1047 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1048 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1049 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1050 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
da4e8ca3 1051 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
6f2fad74
NB
1052 NULL \
1053};
1054
1055/*
1056 * Create the needed functions for each fan using the macro defined above
8de57709 1057 * (4 fans are supported)
6f2fad74
NB
1058 */
1059sysfs_fan_speeds_offset(1);
1060sysfs_fan_speeds_offset(2);
8de57709
RR
1061sysfs_fan_speeds_offset(3);
1062sysfs_fan_speeds_offset(4);
6f2fad74
NB
1063
1064static const struct attribute_group fan_attribute_groups[] = {
1065 { .attrs = fan1_attributes },
8de57709
RR
1066 { .attrs = fan2_attributes },
1067 { .attrs = fan3_attributes },
1068 { .attrs = fan4_attributes },
6f2fad74
NB
1069};
1070
1071/*
1072 * Temperature sensors sysfs entries.
1073 */
1074static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1075 applesmc_show_temperature, NULL, 0);
1076static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1077 applesmc_show_temperature, NULL, 1);
1078static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1079 applesmc_show_temperature, NULL, 2);
1080static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1081 applesmc_show_temperature, NULL, 3);
1082static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1083 applesmc_show_temperature, NULL, 4);
1084static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1085 applesmc_show_temperature, NULL, 5);
1086static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1087 applesmc_show_temperature, NULL, 6);
1088static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1089 applesmc_show_temperature, NULL, 7);
1090static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1091 applesmc_show_temperature, NULL, 8);
1092static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1093 applesmc_show_temperature, NULL, 9);
1094static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1095 applesmc_show_temperature, NULL, 10);
1096static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1097 applesmc_show_temperature, NULL, 11);
8de57709
RR
1098static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1099 applesmc_show_temperature, NULL, 12);
1100static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1101 applesmc_show_temperature, NULL, 13);
1102static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1103 applesmc_show_temperature, NULL, 14);
1104static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1105 applesmc_show_temperature, NULL, 15);
1106static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1107 applesmc_show_temperature, NULL, 16);
1108static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1109 applesmc_show_temperature, NULL, 17);
1110static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1111 applesmc_show_temperature, NULL, 18);
1112static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1113 applesmc_show_temperature, NULL, 19);
1114static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1115 applesmc_show_temperature, NULL, 20);
1116static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1117 applesmc_show_temperature, NULL, 21);
1118static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1119 applesmc_show_temperature, NULL, 22);
1120static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1121 applesmc_show_temperature, NULL, 23);
1122static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1123 applesmc_show_temperature, NULL, 24);
1124static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1125 applesmc_show_temperature, NULL, 25);
1126static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1127 applesmc_show_temperature, NULL, 26);
1128static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1129 applesmc_show_temperature, NULL, 27);
1130static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1131 applesmc_show_temperature, NULL, 28);
1132static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1133 applesmc_show_temperature, NULL, 29);
1134static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1135 applesmc_show_temperature, NULL, 30);
1136static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1137 applesmc_show_temperature, NULL, 31);
1138static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1139 applesmc_show_temperature, NULL, 32);
1140static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1141 applesmc_show_temperature, NULL, 33);
1142static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1143 applesmc_show_temperature, NULL, 34);
6f2fad74
NB
1144
1145static struct attribute *temperature_attributes[] = {
1146 &sensor_dev_attr_temp1_input.dev_attr.attr,
1147 &sensor_dev_attr_temp2_input.dev_attr.attr,
1148 &sensor_dev_attr_temp3_input.dev_attr.attr,
1149 &sensor_dev_attr_temp4_input.dev_attr.attr,
1150 &sensor_dev_attr_temp5_input.dev_attr.attr,
1151 &sensor_dev_attr_temp6_input.dev_attr.attr,
1152 &sensor_dev_attr_temp7_input.dev_attr.attr,
1153 &sensor_dev_attr_temp8_input.dev_attr.attr,
1154 &sensor_dev_attr_temp9_input.dev_attr.attr,
1155 &sensor_dev_attr_temp10_input.dev_attr.attr,
1156 &sensor_dev_attr_temp11_input.dev_attr.attr,
1157 &sensor_dev_attr_temp12_input.dev_attr.attr,
8de57709
RR
1158 &sensor_dev_attr_temp13_input.dev_attr.attr,
1159 &sensor_dev_attr_temp14_input.dev_attr.attr,
1160 &sensor_dev_attr_temp15_input.dev_attr.attr,
1161 &sensor_dev_attr_temp16_input.dev_attr.attr,
1162 &sensor_dev_attr_temp17_input.dev_attr.attr,
1163 &sensor_dev_attr_temp18_input.dev_attr.attr,
1164 &sensor_dev_attr_temp19_input.dev_attr.attr,
1165 &sensor_dev_attr_temp20_input.dev_attr.attr,
1166 &sensor_dev_attr_temp21_input.dev_attr.attr,
1167 &sensor_dev_attr_temp22_input.dev_attr.attr,
1168 &sensor_dev_attr_temp23_input.dev_attr.attr,
1169 &sensor_dev_attr_temp24_input.dev_attr.attr,
1170 &sensor_dev_attr_temp25_input.dev_attr.attr,
1171 &sensor_dev_attr_temp26_input.dev_attr.attr,
1172 &sensor_dev_attr_temp27_input.dev_attr.attr,
1173 &sensor_dev_attr_temp28_input.dev_attr.attr,
1174 &sensor_dev_attr_temp29_input.dev_attr.attr,
1175 &sensor_dev_attr_temp30_input.dev_attr.attr,
1176 &sensor_dev_attr_temp31_input.dev_attr.attr,
1177 &sensor_dev_attr_temp32_input.dev_attr.attr,
1178 &sensor_dev_attr_temp33_input.dev_attr.attr,
1179 &sensor_dev_attr_temp34_input.dev_attr.attr,
1180 &sensor_dev_attr_temp35_input.dev_attr.attr,
6f2fad74
NB
1181 NULL
1182};
1183
1184static const struct attribute_group temperature_attributes_group =
1185 { .attrs = temperature_attributes };
1186
1187/* Module stuff */
1188
1189/*
1190 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1191 */
1855256c 1192static int applesmc_dmi_match(const struct dmi_system_id *id)
6f2fad74
NB
1193{
1194 int i = 0;
1195 struct dmi_match_data* dmi_data = id->driver_data;
1196 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1197 applesmc_accelerometer = dmi_data->accelerometer;
1198 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1199 applesmc_accelerometer ? "with" : "without");
1200 applesmc_light = dmi_data->light;
1201 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1202 applesmc_light ? "with" : "without");
1203
1204 applesmc_temperature_set = dmi_data->temperature_set;
1205 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1206 i++;
1207 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1208 return 1;
1209}
1210
1211/* Create accelerometer ressources */
1212static int applesmc_create_accelerometer(void)
1213{
d5cf2b99 1214 struct input_dev *idev;
6f2fad74
NB
1215 int ret;
1216
1217 ret = sysfs_create_group(&pdev->dev.kobj,
1218 &accelerometer_attributes_group);
1219 if (ret)
1220 goto out;
1221
d5cf2b99 1222 applesmc_idev = input_allocate_polled_device();
6f2fad74
NB
1223 if (!applesmc_idev) {
1224 ret = -ENOMEM;
1225 goto out_sysfs;
1226 }
1227
d5cf2b99
DT
1228 applesmc_idev->poll = applesmc_idev_poll;
1229 applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1230
6f2fad74
NB
1231 /* initial calibrate for the input device */
1232 applesmc_calibrate();
1233
d5cf2b99
DT
1234 /* initialize the input device */
1235 idev = applesmc_idev->input;
1236 idev->name = "applesmc";
1237 idev->id.bustype = BUS_HOST;
1238 idev->dev.parent = &pdev->dev;
7b19ada2 1239 idev->evbit[0] = BIT_MASK(EV_ABS);
d5cf2b99 1240 input_set_abs_params(idev, ABS_X,
6f2fad74 1241 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
d5cf2b99 1242 input_set_abs_params(idev, ABS_Y,
6f2fad74
NB
1243 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1244
d5cf2b99 1245 ret = input_register_polled_device(applesmc_idev);
6f2fad74
NB
1246 if (ret)
1247 goto out_idev;
1248
6f2fad74
NB
1249 return 0;
1250
1251out_idev:
d5cf2b99 1252 input_free_polled_device(applesmc_idev);
6f2fad74
NB
1253
1254out_sysfs:
1255 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1256
1257out:
1258 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1259 return ret;
1260}
1261
1262/* Release all ressources used by the accelerometer */
1263static void applesmc_release_accelerometer(void)
1264{
d5cf2b99
DT
1265 input_unregister_polled_device(applesmc_idev);
1266 input_free_polled_device(applesmc_idev);
6f2fad74
NB
1267 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1268}
1269
1270static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1271/* MacBook Pro: accelerometer, backlight and temperature set 0 */
1272 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
cd19ba13 1273/* MacBook2: accelerometer and temperature set 1 */
1bed24b9 1274 { .accelerometer = 1, .light = 0, .temperature_set = 1 },
cd19ba13
RO
1275/* MacBook: accelerometer and temperature set 2 */
1276 { .accelerometer = 1, .light = 0, .temperature_set = 2 },
1277/* MacMini: temperature set 3 */
8de57709 1278 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
cd19ba13
RO
1279/* MacPro: temperature set 4 */
1280 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
9f86f28d
RDI
1281/* iMac: temperature set 5 */
1282 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
468cc032 1283/* MacBook3, MacBook4: accelerometer and temperature set 6 */
f91a79fe 1284 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
f5274c97
HR
1285/* MacBook Air: accelerometer, backlight and temperature set 7 */
1286 { .accelerometer = 1, .light = 1, .temperature_set = 7 },
d7549905
HR
1287/* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1288 { .accelerometer = 1, .light = 1, .temperature_set = 8 },
07e8dbd3
HR
1289/* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1290 { .accelerometer = 1, .light = 1, .temperature_set = 9 },
6e3530fa
HR
1291/* iMac 5: light sensor only, temperature set 10 */
1292 { .accelerometer = 0, .light = 0, .temperature_set = 10 },
181209a1
HR
1293/* MacBook 5: accelerometer, backlight and temperature set 11 */
1294 { .accelerometer = 1, .light = 1, .temperature_set = 11 },
a6660325
HR
1295/* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1296 { .accelerometer = 1, .light = 1, .temperature_set = 12 },
eefc488f
HR
1297/* iMac 8: light sensor only, temperature set 13 */
1298 { .accelerometer = 0, .light = 0, .temperature_set = 13 },
6f2fad74
NB
1299};
1300
1301/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1302 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1303static __initdata struct dmi_system_id applesmc_whitelist[] = {
f5274c97
HR
1304 { applesmc_dmi_match, "Apple MacBook Air", {
1305 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1306 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
7b5e3cb2 1307 &applesmc_dmi_data[7]},
a6660325
HR
1308 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1309 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1310 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1311 &applesmc_dmi_data[12]},
d7549905
HR
1312 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1313 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1314 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1315 &applesmc_dmi_data[8]},
07e8dbd3
HR
1316 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1317 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1318 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1319 &applesmc_dmi_data[9]},
6f2fad74
NB
1320 { applesmc_dmi_match, "Apple MacBook Pro", {
1321 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1322 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
7b5e3cb2 1323 &applesmc_dmi_data[0]},
f91a79fe 1324 { applesmc_dmi_match, "Apple MacBook (v2)", {
6f2fad74 1325 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
cd19ba13 1326 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
7b5e3cb2 1327 &applesmc_dmi_data[1]},
f91a79fe
GS
1328 { applesmc_dmi_match, "Apple MacBook (v3)", {
1329 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1330 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
7b5e3cb2 1331 &applesmc_dmi_data[6]},
468cc032
HR
1332 { applesmc_dmi_match, "Apple MacBook 4", {
1333 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1334 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1335 &applesmc_dmi_data[6]},
181209a1
HR
1336 { applesmc_dmi_match, "Apple MacBook 5", {
1337 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1338 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1339 &applesmc_dmi_data[11]},
cd19ba13
RO
1340 { applesmc_dmi_match, "Apple MacBook", {
1341 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1342 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
7b5e3cb2 1343 &applesmc_dmi_data[2]},
6f2fad74
NB
1344 { applesmc_dmi_match, "Apple Macmini", {
1345 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1346 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
7b5e3cb2 1347 &applesmc_dmi_data[3]},
8de57709
RR
1348 { applesmc_dmi_match, "Apple MacPro2", {
1349 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1350 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
7b5e3cb2 1351 &applesmc_dmi_data[4]},
eefc488f
HR
1352 { applesmc_dmi_match, "Apple iMac 8", {
1353 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1354 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1355 &applesmc_dmi_data[13]},
6e3530fa
HR
1356 { applesmc_dmi_match, "Apple iMac 5", {
1357 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1358 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1359 &applesmc_dmi_data[10]},
9f86f28d
RDI
1360 { applesmc_dmi_match, "Apple iMac", {
1361 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1362 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
7b5e3cb2 1363 &applesmc_dmi_data[5]},
6f2fad74
NB
1364 { .ident = NULL }
1365};
1366
1367static int __init applesmc_init(void)
1368{
1369 int ret;
1370 int count;
1371 int i;
1372
6f2fad74
NB
1373 if (!dmi_check_system(applesmc_whitelist)) {
1374 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1375 ret = -ENODEV;
1376 goto out;
1377 }
1378
1379 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1380 "applesmc")) {
1381 ret = -ENXIO;
1382 goto out;
1383 }
1384
1385 ret = platform_driver_register(&applesmc_driver);
1386 if (ret)
1387 goto out_region;
1388
ddfbf2af
JD
1389 pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1390 NULL, 0);
6f2fad74
NB
1391 if (IS_ERR(pdev)) {
1392 ret = PTR_ERR(pdev);
1393 goto out_driver;
1394 }
1395
fa74419b 1396 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
6996abf0
NB
1397 if (ret)
1398 goto out_device;
fa74419b 1399
6f2fad74
NB
1400 /* Create key enumeration sysfs files */
1401 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1402 if (ret)
6996abf0 1403 goto out_name;
6f2fad74
NB
1404
1405 /* create fan files */
1406 count = applesmc_get_fan_count();
1407 if (count < 0) {
1408 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1409 } else {
1410 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1411
1412 switch (count) {
1413 default:
8de57709
RR
1414 printk(KERN_WARNING "applesmc: More than 4 fans found,"
1415 " but at most 4 fans are supported"
6f2fad74 1416 " by the driver.\n");
8de57709
RR
1417 case 4:
1418 ret = sysfs_create_group(&pdev->dev.kobj,
1419 &fan_attribute_groups[3]);
1420 if (ret)
1421 goto out_key_enumeration;
1422 case 3:
1423 ret = sysfs_create_group(&pdev->dev.kobj,
1424 &fan_attribute_groups[2]);
1425 if (ret)
1426 goto out_key_enumeration;
6f2fad74
NB
1427 case 2:
1428 ret = sysfs_create_group(&pdev->dev.kobj,
1429 &fan_attribute_groups[1]);
1430 if (ret)
1431 goto out_key_enumeration;
1432 case 1:
1433 ret = sysfs_create_group(&pdev->dev.kobj,
1434 &fan_attribute_groups[0]);
1435 if (ret)
1436 goto out_fan_1;
1437 case 0:
1438 ;
1439 }
1440 }
1441
1442 for (i = 0;
1443 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1444 i++) {
1445 if (temperature_attributes[i] == NULL) {
1446 printk(KERN_ERR "applesmc: More temperature sensors "
1447 "in temperature_sensors_sets (at least %i)"
1448 "than available sysfs files in "
1449 "temperature_attributes (%i), please report "
1450 "this bug.\n", i, i-1);
1451 goto out_temperature;
1452 }
1453 ret = sysfs_create_file(&pdev->dev.kobj,
1454 temperature_attributes[i]);
1455 if (ret)
1456 goto out_temperature;
1457 }
1458
1459 if (applesmc_accelerometer) {
1460 ret = applesmc_create_accelerometer();
1461 if (ret)
1462 goto out_temperature;
1463 }
1464
1465 if (applesmc_light) {
1466 /* Add light sensor file */
1467 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1468 if (ret)
1469 goto out_accelerometer;
1470
1471 /* Create the workqueue */
1472 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1473 if (!applesmc_led_wq) {
1474 ret = -ENOMEM;
1475 goto out_light_sysfs;
1476 }
1477
1478 /* register as a led device */
1479 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1480 if (ret < 0)
1481 goto out_light_wq;
1482 }
1483
1beeffe4
TJ
1484 hwmon_dev = hwmon_device_register(&pdev->dev);
1485 if (IS_ERR(hwmon_dev)) {
1486 ret = PTR_ERR(hwmon_dev);
6f2fad74
NB
1487 goto out_light_ledclass;
1488 }
1489
1490 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1491
1492 return 0;
1493
1494out_light_ledclass:
1495 if (applesmc_light)
1496 led_classdev_unregister(&applesmc_backlight);
1497out_light_wq:
1498 if (applesmc_light)
1499 destroy_workqueue(applesmc_led_wq);
1500out_light_sysfs:
1501 if (applesmc_light)
1502 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1503out_accelerometer:
1504 if (applesmc_accelerometer)
1505 applesmc_release_accelerometer();
1506out_temperature:
1507 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1508 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1509out_fan_1:
1510 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1511out_key_enumeration:
1512 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
6996abf0
NB
1513out_name:
1514 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
6f2fad74
NB
1515out_device:
1516 platform_device_unregister(pdev);
1517out_driver:
1518 platform_driver_unregister(&applesmc_driver);
1519out_region:
1520 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1521out:
1522 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1523 return ret;
1524}
1525
1526static void __exit applesmc_exit(void)
1527{
1beeffe4 1528 hwmon_device_unregister(hwmon_dev);
6f2fad74
NB
1529 if (applesmc_light) {
1530 led_classdev_unregister(&applesmc_backlight);
1531 destroy_workqueue(applesmc_led_wq);
1532 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1533 }
1534 if (applesmc_accelerometer)
1535 applesmc_release_accelerometer();
1536 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1537 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1538 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1539 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
6996abf0 1540 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
6f2fad74
NB
1541 platform_device_unregister(pdev);
1542 platform_driver_unregister(&applesmc_driver);
1543 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1544
1545 printk(KERN_INFO "applesmc: driver unloaded.\n");
1546}
1547
1548module_init(applesmc_init);
1549module_exit(applesmc_exit);
1550
1551MODULE_AUTHOR("Nicolas Boichat");
1552MODULE_DESCRIPTION("Apple SMC");
1553MODULE_LICENSE("GPL v2");
This page took 0.258703 seconds and 5 git commands to generate.