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