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