• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/hwmon/
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>
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/* 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
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" /* r-o ui32 */
62
63#define LIGHT_SENSOR_LEFT_KEY	"ALV0" /* r-o {alv (6-10 bytes) */
64#define LIGHT_SENSOR_RIGHT_KEY	"ALV1" /* r-o {alv (6-10 bytes) */
65#define BACKLIGHT_KEY		"LKSB" /* w-o {lkb (2 bytes) */
66
67#define CLAMSHELL_KEY		"MSLD" /* r-o ui8 (unused) */
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).
85 */
86static const char *temperature_sensors_sets[][41] = {
87/* Set 0: Macbook Pro */
88	{ "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
89	  "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
90/* Set 1: Macbook2 set */
91	{ "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "TTF0", "Th0H",
92	  "Th0S", "Th1H", NULL },
93/* Set 2: Macbook set */
94	{ "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S",
95	  "Th1H", "Ts0P", NULL },
96/* Set 3: Macmini set */
97	{ "TC0D", "TC0P", NULL },
98/* Set 4: Mac Pro (2 x Quad-Core) */
99	{ "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
100	  "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P",
101	  "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S",
102	  "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P",
103	  "TM9S", "TN0H", "TS0C", NULL },
104/* Set 5: iMac */
105	{ "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P",
106	  "Tp0C", NULL },
107/* Set 6: Macbook3 set */
108	{ "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H",
109	  "Th0S", "Th1H", NULL },
110/* Set 7: Macbook Air */
111	{ "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TC0P", "TCFP",
112	  "TTF0", "TW0P", "Th0H", "Tp0P", "TpFP", "Ts0P", "Ts0S", NULL },
113/* Set 8: Macbook Pro 4,1 (Penryn) */
114	{ "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", "Th0H",
115	  "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
116/* Set 9: Macbook Pro 3,1 (Santa Rosa) */
117	{ "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P",
118	  "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
119/* Set 10: iMac 5,1 */
120	{ "TA0P", "TC0D", "TC0P", "TG0D", "TH0P", "TO0P", "Tm0P", NULL },
121/* Set 11: Macbook 5,1 */
122	{ "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0P", "TN0D", "TN0P",
123	  "TTF0", "Th0H", "Th1H", "ThFH", "Ts0P", "Ts0S", NULL },
124/* Set 12: Macbook Pro 5,1 */
125	{ "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D",
126	  "TG0F", "TG0H", "TG0P", "TG0T", "TG1H", "TN0D", "TN0P", "TTF0",
127	  "Th2H", "Tm0P", "Ts0P", "Ts0S", NULL },
128/* Set 13: iMac 8,1 */
129	{ "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P",
130	  "TL0P", "TO0P", "TW0P", "Tm0P", "Tp0P", NULL },
131/* Set 14: iMac 6,1 */
132	{ "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P",
133	  "TO0P", "Tp0P", NULL },
134/* Set 15: MacBook Air 2,1 */
135	{ "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TN0D", "TTF0",
136	  "TV0P", "TVFP", "TW0P", "Th0P", "Tp0P", "Tp1P", "TpFP", "Ts0P",
137	  "Ts0S", NULL },
138/* Set 16: Mac Pro 3,1 (2 x Quad-Core) */
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/* Set 17: iMac 9,1 */
146	{ "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P",
147	  "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL },
148/* Set 18: MacBook Pro 2,2 */
149	{ "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0",
150	  "Th0H", "Th1H", "Tm0P", "Ts0P", NULL },
151/* Set 19: Macbook Pro 5,3 */
152	{ "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D",
153	  "TG0F", "TG0H", "TG0P", "TG0T", "TN0D", "TN0P", "TTF0", "Th2H",
154	  "Tm0P", "Ts0P", "Ts0S", NULL },
155/* Set 20: MacBook Pro 5,4 */
156	{ "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TN0D",
157	  "TN0P", "TTF0", "Th2H", "Ts0P", "Ts0S", NULL },
158/* Set 21: MacBook Pro 6,2 */
159	{ "TB0T", "TB1T", "TB2T", "TC0C", "TC0D", "TC0P", "TC1C", "TG0D",
160	  "TG0P", "TG0T", "TMCD", "TP0P", "TPCD", "Th1H", "Th2H", "Tm0P",
161	  "Ts0P", "Ts0S", NULL },
162/* Set 22: MacBook Pro 7,1 */
163	{ "TB0T", "TB1T", "TB2T", "TC0D", "TC0P", "TN0D", "TN0P", "TN0S",
164	  "TN1D", "TN1F", "TN1G", "TN1S", "Th1H", "Ts0P", "Ts0S", NULL },
165/* Set 23: MacBook Air 3,1 */
166	{ "TB0T", "TB1T", "TB2T", "TC0D", "TC0E", "TC0P", "TC1E", "TCZ3",
167	  "TCZ4", "TCZ5", "TG0E", "TG1E", "TG2E", "TGZ3", "TGZ4", "TGZ5",
168	  "TH0F", "TH0O", "TM0P" },
169};
170
171/* List of keys used to read/write fan speeds */
172static const char* fan_speed_keys[] = {
173	FAN_ACTUAL_SPEED,
174	FAN_MIN_SPEED,
175	FAN_MAX_SPEED,
176	FAN_SAFE_SPEED,
177	FAN_TARGET_SPEED
178};
179
180#define INIT_TIMEOUT_MSECS	5000	/* wait up to 5s for device init ... */
181#define INIT_WAIT_MSECS		50	/* ... in 50ms increments */
182
183#define APPLESMC_POLL_INTERVAL	50	/* msecs */
184#define APPLESMC_INPUT_FUZZ	4	/* input event threshold */
185#define APPLESMC_INPUT_FLAT	4
186
187#define SENSOR_X 0
188#define SENSOR_Y 1
189#define SENSOR_Z 2
190
191/* Structure to be passed to DMI_MATCH function */
192struct dmi_match_data {
193/* Indicates whether this computer has an accelerometer. */
194	int accelerometer;
195/* Indicates whether this computer has light sensors and keyboard backlight. */
196	int light;
197/* Indicates which temperature sensors set to use. */
198	int temperature_set;
199};
200
201static const int debug;
202static struct platform_device *pdev;
203static s16 rest_x;
204static s16 rest_y;
205static u8 backlight_state[2];
206
207static struct device *hwmon_dev;
208static struct input_polled_dev *applesmc_idev;
209
210/* Indicates whether this computer has an accelerometer. */
211static unsigned int applesmc_accelerometer;
212
213/* Indicates whether this computer has light sensors and keyboard backlight. */
214static unsigned int applesmc_light;
215
216/* The number of fans handled by the driver */
217static unsigned int fans_handled;
218
219/* Indicates which temperature sensors set to use. */
220static unsigned int applesmc_temperature_set;
221
222static DEFINE_MUTEX(applesmc_lock);
223
224/*
225 * Last index written to key_at_index sysfs file, and value to use for all other
226 * key_at_index_* sysfs files.
227 */
228static unsigned int key_at_index;
229
230static struct workqueue_struct *applesmc_led_wq;
231
232/*
233 * __wait_status - Wait up to 32ms for the status port to get a certain value
234 * (masked with 0x0f), returning zero if the value is obtained.  Callers must
235 * hold applesmc_lock.
236 */
237static int __wait_status(u8 val)
238{
239	int us;
240
241	val = val & APPLESMC_STATUS_MASK;
242
243	for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
244		udelay(us);
245		if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
246			if (debug)
247				printk(KERN_DEBUG
248					"Waited %d us for status %x\n",
249					2 * us - APPLESMC_MIN_WAIT, val);
250			return 0;
251		}
252	}
253
254	printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
255						val, inb(APPLESMC_CMD_PORT));
256
257	return -EIO;
258}
259
260/*
261 * special treatment of command port - on newer macbooks, it seems necessary
262 * to resend the command byte before polling the status again. Callers must
263 * hold applesmc_lock.
264 */
265static int send_command(u8 cmd)
266{
267	int us;
268	for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
269		outb(cmd, APPLESMC_CMD_PORT);
270		udelay(us);
271		if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
272			return 0;
273	}
274	printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
275		cmd, inb(APPLESMC_CMD_PORT));
276	return -EIO;
277}
278
279/*
280 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
281 * Returns zero on success or a negative error on failure. Callers must
282 * hold applesmc_lock.
283 */
284static int applesmc_read_key(const char* key, u8* buffer, u8 len)
285{
286	int i;
287
288	if (len > APPLESMC_MAX_DATA_LENGTH) {
289		printk(KERN_ERR	"applesmc_read_key: cannot read more than "
290					"%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
291		return -EINVAL;
292	}
293
294	if (send_command(APPLESMC_READ_CMD))
295		return -EIO;
296
297	for (i = 0; i < 4; i++) {
298		outb(key[i], APPLESMC_DATA_PORT);
299		if (__wait_status(0x04))
300			return -EIO;
301	}
302	if (debug)
303		printk(KERN_DEBUG "<%s", key);
304
305	outb(len, APPLESMC_DATA_PORT);
306	if (debug)
307		printk(KERN_DEBUG ">%x", len);
308
309	for (i = 0; i < len; i++) {
310		if (__wait_status(0x05))
311			return -EIO;
312		buffer[i] = inb(APPLESMC_DATA_PORT);
313		if (debug)
314			printk(KERN_DEBUG "<%x", buffer[i]);
315	}
316	if (debug)
317		printk(KERN_DEBUG "\n");
318
319	return 0;
320}
321
322/*
323 * applesmc_write_key - writes len bytes from buffer to a given key.
324 * Returns zero on success or a negative error on failure. Callers must
325 * hold applesmc_lock.
326 */
327static int applesmc_write_key(const char* key, u8* buffer, u8 len)
328{
329	int i;
330
331	if (len > APPLESMC_MAX_DATA_LENGTH) {
332		printk(KERN_ERR	"applesmc_write_key: cannot write more than "
333					"%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
334		return -EINVAL;
335	}
336
337	if (send_command(APPLESMC_WRITE_CMD))
338		return -EIO;
339
340	for (i = 0; i < 4; i++) {
341		outb(key[i], APPLESMC_DATA_PORT);
342		if (__wait_status(0x04))
343			return -EIO;
344	}
345
346	outb(len, APPLESMC_DATA_PORT);
347
348	for (i = 0; i < len; i++) {
349		if (__wait_status(0x04))
350			return -EIO;
351		outb(buffer[i], APPLESMC_DATA_PORT);
352	}
353
354	return 0;
355}
356
357/*
358 * applesmc_get_key_at_index - get key at index, and put the result in key
359 * (char[6]). Returns zero on success or a negative error on failure. Callers
360 * must hold applesmc_lock.
361 */
362static int applesmc_get_key_at_index(int index, char* key)
363{
364	int i;
365	u8 readkey[4];
366	readkey[0] = index >> 24;
367	readkey[1] = index >> 16;
368	readkey[2] = index >> 8;
369	readkey[3] = index;
370
371	if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
372		return -EIO;
373
374	for (i = 0; i < 4; i++) {
375		outb(readkey[i], APPLESMC_DATA_PORT);
376		if (__wait_status(0x04))
377			return -EIO;
378	}
379
380	outb(4, APPLESMC_DATA_PORT);
381
382	for (i = 0; i < 4; i++) {
383		if (__wait_status(0x05))
384			return -EIO;
385		key[i] = inb(APPLESMC_DATA_PORT);
386	}
387	key[4] = 0;
388
389	return 0;
390}
391
392/*
393 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
394 * Returns zero on success or a negative error on failure. Callers must
395 * hold applesmc_lock.
396 */
397static int applesmc_get_key_type(char* key, char* type)
398{
399	int i;
400
401	if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
402		return -EIO;
403
404	for (i = 0; i < 4; i++) {
405		outb(key[i], APPLESMC_DATA_PORT);
406		if (__wait_status(0x04))
407			return -EIO;
408	}
409
410	outb(6, APPLESMC_DATA_PORT);
411
412	for (i = 0; i < 6; i++) {
413		if (__wait_status(0x05))
414			return -EIO;
415		type[i] = inb(APPLESMC_DATA_PORT);
416	}
417	type[5] = 0;
418
419	return 0;
420}
421
422/*
423 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
424 * hold applesmc_lock.
425 */
426static int applesmc_read_motion_sensor(int index, s16* value)
427{
428	u8 buffer[2];
429	int ret;
430
431	switch (index) {
432	case SENSOR_X:
433		ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
434		break;
435	case SENSOR_Y:
436		ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
437		break;
438	case SENSOR_Z:
439		ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
440		break;
441	default:
442		ret = -EINVAL;
443	}
444
445	*value = ((s16)buffer[0] << 8) | buffer[1];
446
447	return ret;
448}
449
450/*
451 * applesmc_device_init - initialize the accelerometer.  Can sleep.
452 */
453static void applesmc_device_init(void)
454{
455	int total;
456	u8 buffer[2];
457
458	if (!applesmc_accelerometer)
459		return;
460
461	mutex_lock(&applesmc_lock);
462
463	for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
464		if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
465				(buffer[0] != 0x00 || buffer[1] != 0x00))
466			goto out;
467		buffer[0] = 0xe0;
468		buffer[1] = 0x00;
469		applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
470		msleep(INIT_WAIT_MSECS);
471	}
472
473	printk(KERN_WARNING "applesmc: failed to init the device\n");
474
475out:
476	mutex_unlock(&applesmc_lock);
477}
478
479/*
480 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
481 * applesmc_lock.
482 */
483static int applesmc_get_fan_count(void)
484{
485	int ret;
486	u8 buffer[1];
487
488	mutex_lock(&applesmc_lock);
489
490	ret = applesmc_read_key(FANS_COUNT, buffer, 1);
491
492	mutex_unlock(&applesmc_lock);
493	if (ret)
494		return ret;
495	else
496		return buffer[0];
497}
498
499/* Device model stuff */
500static int applesmc_probe(struct platform_device *dev)
501{
502	applesmc_device_init();
503
504	return 0;
505}
506
507/* Synchronize device with memorized backlight state */
508static int applesmc_pm_resume(struct device *dev)
509{
510	mutex_lock(&applesmc_lock);
511	if (applesmc_light)
512		applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
513	mutex_unlock(&applesmc_lock);
514	return 0;
515}
516
517/* Reinitialize device on resume from hibernation */
518static int applesmc_pm_restore(struct device *dev)
519{
520	applesmc_device_init();
521	return applesmc_pm_resume(dev);
522}
523
524static const struct dev_pm_ops applesmc_pm_ops = {
525	.resume = applesmc_pm_resume,
526	.restore = applesmc_pm_restore,
527};
528
529static struct platform_driver applesmc_driver = {
530	.probe = applesmc_probe,
531	.driver	= {
532		.name = "applesmc",
533		.owner = THIS_MODULE,
534		.pm = &applesmc_pm_ops,
535	},
536};
537
538/*
539 * applesmc_calibrate - Set our "resting" values.  Callers must
540 * hold applesmc_lock.
541 */
542static void applesmc_calibrate(void)
543{
544	applesmc_read_motion_sensor(SENSOR_X, &rest_x);
545	applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
546	rest_x = -rest_x;
547}
548
549static void applesmc_idev_poll(struct input_polled_dev *dev)
550{
551	struct input_dev *idev = dev->input;
552	s16 x, y;
553
554	mutex_lock(&applesmc_lock);
555
556	if (applesmc_read_motion_sensor(SENSOR_X, &x))
557		goto out;
558	if (applesmc_read_motion_sensor(SENSOR_Y, &y))
559		goto out;
560
561	x = -x;
562	input_report_abs(idev, ABS_X, x - rest_x);
563	input_report_abs(idev, ABS_Y, y - rest_y);
564	input_sync(idev);
565
566out:
567	mutex_unlock(&applesmc_lock);
568}
569
570/* Sysfs Files */
571
572static ssize_t applesmc_name_show(struct device *dev,
573				   struct device_attribute *attr, char *buf)
574{
575	return snprintf(buf, PAGE_SIZE, "applesmc\n");
576}
577
578static ssize_t applesmc_position_show(struct device *dev,
579				   struct device_attribute *attr, char *buf)
580{
581	int ret;
582	s16 x, y, z;
583
584	mutex_lock(&applesmc_lock);
585
586	ret = applesmc_read_motion_sensor(SENSOR_X, &x);
587	if (ret)
588		goto out;
589	ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
590	if (ret)
591		goto out;
592	ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
593	if (ret)
594		goto out;
595
596out:
597	mutex_unlock(&applesmc_lock);
598	if (ret)
599		return ret;
600	else
601		return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
602}
603
604static ssize_t applesmc_light_show(struct device *dev,
605				struct device_attribute *attr, char *sysfsbuf)
606{
607	static int data_length;
608	int ret;
609	u8 left = 0, right = 0;
610	u8 buffer[10], query[6];
611
612	mutex_lock(&applesmc_lock);
613
614	if (!data_length) {
615		ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
616		if (ret)
617			goto out;
618		data_length = clamp_val(query[0], 0, 10);
619		printk(KERN_INFO "applesmc: light sensor data length set to "
620			"%d\n", data_length);
621	}
622
623	ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
624	/* newer macbooks report a single 10-bit bigendian value */
625	if (data_length == 10) {
626		left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2;
627		goto out;
628	}
629	left = buffer[2];
630	if (ret)
631		goto out;
632	ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
633	right = buffer[2];
634
635out:
636	mutex_unlock(&applesmc_lock);
637	if (ret)
638		return ret;
639	else
640		return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
641}
642
643/* Displays sensor key as label */
644static ssize_t applesmc_show_sensor_label(struct device *dev,
645			struct device_attribute *devattr, char *sysfsbuf)
646{
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	return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
652}
653
654/* Displays degree Celsius * 1000 */
655static ssize_t applesmc_show_temperature(struct device *dev,
656			struct device_attribute *devattr, char *sysfsbuf)
657{
658	int ret;
659	u8 buffer[2];
660	unsigned int temp;
661	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
662	const char* key =
663		temperature_sensors_sets[applesmc_temperature_set][attr->index];
664
665	mutex_lock(&applesmc_lock);
666
667	ret = applesmc_read_key(key, buffer, 2);
668	temp = buffer[0]*1000;
669	temp += (buffer[1] >> 6) * 250;
670
671	mutex_unlock(&applesmc_lock);
672
673	if (ret)
674		return ret;
675	else
676		return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
677}
678
679static ssize_t applesmc_show_fan_speed(struct device *dev,
680				struct device_attribute *attr, char *sysfsbuf)
681{
682	int ret;
683	unsigned int speed = 0;
684	char newkey[5];
685	u8 buffer[2];
686	struct sensor_device_attribute_2 *sensor_attr =
687						to_sensor_dev_attr_2(attr);
688
689	newkey[0] = fan_speed_keys[sensor_attr->nr][0];
690	newkey[1] = '0' + sensor_attr->index;
691	newkey[2] = fan_speed_keys[sensor_attr->nr][2];
692	newkey[3] = fan_speed_keys[sensor_attr->nr][3];
693	newkey[4] = 0;
694
695	mutex_lock(&applesmc_lock);
696
697	ret = applesmc_read_key(newkey, buffer, 2);
698	speed = ((buffer[0] << 8 | buffer[1]) >> 2);
699
700	mutex_unlock(&applesmc_lock);
701	if (ret)
702		return ret;
703	else
704		return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
705}
706
707static ssize_t applesmc_store_fan_speed(struct device *dev,
708					struct device_attribute *attr,
709					const char *sysfsbuf, size_t count)
710{
711	int ret;
712	u32 speed;
713	char newkey[5];
714	u8 buffer[2];
715	struct sensor_device_attribute_2 *sensor_attr =
716						to_sensor_dev_attr_2(attr);
717
718	speed = simple_strtoul(sysfsbuf, NULL, 10);
719
720	if (speed > 0x4000) /* Bigger than a 14-bit value */
721		return -EINVAL;
722
723	newkey[0] = fan_speed_keys[sensor_attr->nr][0];
724	newkey[1] = '0' + sensor_attr->index;
725	newkey[2] = fan_speed_keys[sensor_attr->nr][2];
726	newkey[3] = fan_speed_keys[sensor_attr->nr][3];
727	newkey[4] = 0;
728
729	mutex_lock(&applesmc_lock);
730
731	buffer[0] = (speed >> 6) & 0xff;
732	buffer[1] = (speed << 2) & 0xff;
733	ret = applesmc_write_key(newkey, buffer, 2);
734
735	mutex_unlock(&applesmc_lock);
736	if (ret)
737		return ret;
738	else
739		return count;
740}
741
742static ssize_t applesmc_show_fan_manual(struct device *dev,
743			struct device_attribute *devattr, char *sysfsbuf)
744{
745	int ret;
746	u16 manual = 0;
747	u8 buffer[2];
748	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
749
750	mutex_lock(&applesmc_lock);
751
752	ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
753	manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
754
755	mutex_unlock(&applesmc_lock);
756	if (ret)
757		return ret;
758	else
759		return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
760}
761
762static ssize_t applesmc_store_fan_manual(struct device *dev,
763					 struct device_attribute *devattr,
764					 const char *sysfsbuf, size_t count)
765{
766	int ret;
767	u8 buffer[2];
768	u32 input;
769	u16 val;
770	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
771
772	input = simple_strtoul(sysfsbuf, NULL, 10);
773
774	mutex_lock(&applesmc_lock);
775
776	ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
777	val = (buffer[0] << 8 | buffer[1]);
778	if (ret)
779		goto out;
780
781	if (input)
782		val = val | (0x01 << attr->index);
783	else
784		val = val & ~(0x01 << attr->index);
785
786	buffer[0] = (val >> 8) & 0xFF;
787	buffer[1] = val & 0xFF;
788
789	ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
790
791out:
792	mutex_unlock(&applesmc_lock);
793	if (ret)
794		return ret;
795	else
796		return count;
797}
798
799static ssize_t applesmc_show_fan_position(struct device *dev,
800				struct device_attribute *attr, char *sysfsbuf)
801{
802	int ret;
803	char newkey[5];
804	u8 buffer[17];
805	struct sensor_device_attribute_2 *sensor_attr =
806						to_sensor_dev_attr_2(attr);
807
808	newkey[0] = FAN_POSITION[0];
809	newkey[1] = '0' + sensor_attr->index;
810	newkey[2] = FAN_POSITION[2];
811	newkey[3] = FAN_POSITION[3];
812	newkey[4] = 0;
813
814	mutex_lock(&applesmc_lock);
815
816	ret = applesmc_read_key(newkey, buffer, 16);
817	buffer[16] = 0;
818
819	mutex_unlock(&applesmc_lock);
820	if (ret)
821		return ret;
822	else
823		return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
824}
825
826static ssize_t applesmc_calibrate_show(struct device *dev,
827				struct device_attribute *attr, char *sysfsbuf)
828{
829	return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
830}
831
832static ssize_t applesmc_calibrate_store(struct device *dev,
833	struct device_attribute *attr, const char *sysfsbuf, size_t count)
834{
835	mutex_lock(&applesmc_lock);
836	applesmc_calibrate();
837	mutex_unlock(&applesmc_lock);
838
839	return count;
840}
841
842static void applesmc_backlight_set(struct work_struct *work)
843{
844	mutex_lock(&applesmc_lock);
845	applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
846	mutex_unlock(&applesmc_lock);
847}
848static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
849
850static void applesmc_brightness_set(struct led_classdev *led_cdev,
851						enum led_brightness value)
852{
853	int ret;
854
855	backlight_state[0] = value;
856	ret = queue_work(applesmc_led_wq, &backlight_work);
857
858	if (debug && (!ret))
859		printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
860}
861
862static ssize_t applesmc_key_count_show(struct device *dev,
863				struct device_attribute *attr, char *sysfsbuf)
864{
865	int ret;
866	u8 buffer[4];
867	u32 count;
868
869	mutex_lock(&applesmc_lock);
870
871	ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
872	count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
873						((u32)buffer[2]<<8) + buffer[3];
874
875	mutex_unlock(&applesmc_lock);
876	if (ret)
877		return ret;
878	else
879		return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
880}
881
882static ssize_t applesmc_key_at_index_read_show(struct device *dev,
883				struct device_attribute *attr, char *sysfsbuf)
884{
885	char key[5];
886	char info[6];
887	int ret;
888
889	mutex_lock(&applesmc_lock);
890
891	ret = applesmc_get_key_at_index(key_at_index, key);
892
893	if (ret || !key[0]) {
894		mutex_unlock(&applesmc_lock);
895
896		return -EINVAL;
897	}
898
899	ret = applesmc_get_key_type(key, info);
900
901	if (ret) {
902		mutex_unlock(&applesmc_lock);
903
904		return ret;
905	}
906
907	/*
908	 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
909	 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
910	 */
911	ret = applesmc_read_key(key, sysfsbuf, info[0]);
912
913	mutex_unlock(&applesmc_lock);
914
915	if (!ret) {
916		return info[0];
917	} else {
918		return ret;
919	}
920}
921
922static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
923				struct device_attribute *attr, char *sysfsbuf)
924{
925	char key[5];
926	char info[6];
927	int ret;
928
929	mutex_lock(&applesmc_lock);
930
931	ret = applesmc_get_key_at_index(key_at_index, key);
932
933	if (ret || !key[0]) {
934		mutex_unlock(&applesmc_lock);
935
936		return -EINVAL;
937	}
938
939	ret = applesmc_get_key_type(key, info);
940
941	mutex_unlock(&applesmc_lock);
942
943	if (!ret)
944		return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
945	else
946		return ret;
947}
948
949static ssize_t applesmc_key_at_index_type_show(struct device *dev,
950				struct device_attribute *attr, char *sysfsbuf)
951{
952	char key[5];
953	char info[6];
954	int ret;
955
956	mutex_lock(&applesmc_lock);
957
958	ret = applesmc_get_key_at_index(key_at_index, key);
959
960	if (ret || !key[0]) {
961		mutex_unlock(&applesmc_lock);
962
963		return -EINVAL;
964	}
965
966	ret = applesmc_get_key_type(key, info);
967
968	mutex_unlock(&applesmc_lock);
969
970	if (!ret)
971		return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
972	else
973		return ret;
974}
975
976static ssize_t applesmc_key_at_index_name_show(struct device *dev,
977				struct device_attribute *attr, char *sysfsbuf)
978{
979	char key[5];
980	int ret;
981
982	mutex_lock(&applesmc_lock);
983
984	ret = applesmc_get_key_at_index(key_at_index, key);
985
986	mutex_unlock(&applesmc_lock);
987
988	if (!ret && key[0])
989		return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
990	else
991		return -EINVAL;
992}
993
994static ssize_t applesmc_key_at_index_show(struct device *dev,
995				struct device_attribute *attr, char *sysfsbuf)
996{
997	return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
998}
999
1000static ssize_t applesmc_key_at_index_store(struct device *dev,
1001	struct device_attribute *attr, const char *sysfsbuf, size_t count)
1002{
1003	mutex_lock(&applesmc_lock);
1004
1005	key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
1006
1007	mutex_unlock(&applesmc_lock);
1008
1009	return count;
1010}
1011
1012static struct led_classdev applesmc_backlight = {
1013	.name			= "smc::kbd_backlight",
1014	.default_trigger	= "nand-disk",
1015	.brightness_set		= applesmc_brightness_set,
1016};
1017
1018static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
1019
1020static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
1021static DEVICE_ATTR(calibrate, 0644,
1022			applesmc_calibrate_show, applesmc_calibrate_store);
1023
1024static struct attribute *accelerometer_attributes[] = {
1025	&dev_attr_position.attr,
1026	&dev_attr_calibrate.attr,
1027	NULL
1028};
1029
1030static const struct attribute_group accelerometer_attributes_group =
1031	{ .attrs = accelerometer_attributes };
1032
1033static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
1034
1035static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
1036static DEVICE_ATTR(key_at_index, 0644,
1037		applesmc_key_at_index_show, applesmc_key_at_index_store);
1038static DEVICE_ATTR(key_at_index_name, 0444,
1039					applesmc_key_at_index_name_show, NULL);
1040static DEVICE_ATTR(key_at_index_type, 0444,
1041					applesmc_key_at_index_type_show, NULL);
1042static DEVICE_ATTR(key_at_index_data_length, 0444,
1043				applesmc_key_at_index_data_length_show, NULL);
1044static DEVICE_ATTR(key_at_index_data, 0444,
1045				applesmc_key_at_index_read_show, NULL);
1046
1047static struct attribute *key_enumeration_attributes[] = {
1048	&dev_attr_key_count.attr,
1049	&dev_attr_key_at_index.attr,
1050	&dev_attr_key_at_index_name.attr,
1051	&dev_attr_key_at_index_type.attr,
1052	&dev_attr_key_at_index_data_length.attr,
1053	&dev_attr_key_at_index_data.attr,
1054	NULL
1055};
1056
1057static const struct attribute_group key_enumeration_group =
1058	{ .attrs = key_enumeration_attributes };
1059
1060/*
1061 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1062 *  - show actual speed
1063 *  - show/store minimum speed
1064 *  - show maximum speed
1065 *  - show safe speed
1066 *  - show/store target speed
1067 *  - show/store manual mode
1068 */
1069#define sysfs_fan_speeds_offset(offset) \
1070static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1071			applesmc_show_fan_speed, NULL, 0, offset-1); \
1072\
1073static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1074	applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1075\
1076static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1077			applesmc_show_fan_speed, NULL, 2, offset-1); \
1078\
1079static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1080			applesmc_show_fan_speed, NULL, 3, offset-1); \
1081\
1082static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1083	applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1084\
1085static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1086	applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1087\
1088static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1089	applesmc_show_fan_position, NULL, offset-1); \
1090\
1091static struct attribute *fan##offset##_attributes[] = { \
1092	&sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1093	&sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1094	&sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1095	&sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1096	&sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1097	&sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1098	&sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1099	NULL \
1100};
1101
1102/*
1103 * Create the needed functions for each fan using the macro defined above
1104 * (4 fans are supported)
1105 */
1106sysfs_fan_speeds_offset(1);
1107sysfs_fan_speeds_offset(2);
1108sysfs_fan_speeds_offset(3);
1109sysfs_fan_speeds_offset(4);
1110
1111static const struct attribute_group fan_attribute_groups[] = {
1112	{ .attrs = fan1_attributes },
1113	{ .attrs = fan2_attributes },
1114	{ .attrs = fan3_attributes },
1115	{ .attrs = fan4_attributes },
1116};
1117
1118/*
1119 * Temperature sensors sysfs entries.
1120 */
1121static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO,
1122					applesmc_show_sensor_label, NULL, 0);
1123static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO,
1124					applesmc_show_sensor_label, NULL, 1);
1125static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO,
1126					applesmc_show_sensor_label, NULL, 2);
1127static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO,
1128					applesmc_show_sensor_label, NULL, 3);
1129static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO,
1130					applesmc_show_sensor_label, NULL, 4);
1131static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO,
1132					applesmc_show_sensor_label, NULL, 5);
1133static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO,
1134					applesmc_show_sensor_label, NULL, 6);
1135static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO,
1136					applesmc_show_sensor_label, NULL, 7);
1137static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO,
1138					applesmc_show_sensor_label, NULL, 8);
1139static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO,
1140					applesmc_show_sensor_label, NULL, 9);
1141static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO,
1142					applesmc_show_sensor_label, NULL, 10);
1143static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO,
1144					applesmc_show_sensor_label, NULL, 11);
1145static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO,
1146					applesmc_show_sensor_label, NULL, 12);
1147static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO,
1148					applesmc_show_sensor_label, NULL, 13);
1149static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO,
1150					applesmc_show_sensor_label, NULL, 14);
1151static SENSOR_DEVICE_ATTR(temp16_label, S_IRUGO,
1152					applesmc_show_sensor_label, NULL, 15);
1153static SENSOR_DEVICE_ATTR(temp17_label, S_IRUGO,
1154					applesmc_show_sensor_label, NULL, 16);
1155static SENSOR_DEVICE_ATTR(temp18_label, S_IRUGO,
1156					applesmc_show_sensor_label, NULL, 17);
1157static SENSOR_DEVICE_ATTR(temp19_label, S_IRUGO,
1158					applesmc_show_sensor_label, NULL, 18);
1159static SENSOR_DEVICE_ATTR(temp20_label, S_IRUGO,
1160					applesmc_show_sensor_label, NULL, 19);
1161static SENSOR_DEVICE_ATTR(temp21_label, S_IRUGO,
1162					applesmc_show_sensor_label, NULL, 20);
1163static SENSOR_DEVICE_ATTR(temp22_label, S_IRUGO,
1164					applesmc_show_sensor_label, NULL, 21);
1165static SENSOR_DEVICE_ATTR(temp23_label, S_IRUGO,
1166					applesmc_show_sensor_label, NULL, 22);
1167static SENSOR_DEVICE_ATTR(temp24_label, S_IRUGO,
1168					applesmc_show_sensor_label, NULL, 23);
1169static SENSOR_DEVICE_ATTR(temp25_label, S_IRUGO,
1170					applesmc_show_sensor_label, NULL, 24);
1171static SENSOR_DEVICE_ATTR(temp26_label, S_IRUGO,
1172					applesmc_show_sensor_label, NULL, 25);
1173static SENSOR_DEVICE_ATTR(temp27_label, S_IRUGO,
1174					applesmc_show_sensor_label, NULL, 26);
1175static SENSOR_DEVICE_ATTR(temp28_label, S_IRUGO,
1176					applesmc_show_sensor_label, NULL, 27);
1177static SENSOR_DEVICE_ATTR(temp29_label, S_IRUGO,
1178					applesmc_show_sensor_label, NULL, 28);
1179static SENSOR_DEVICE_ATTR(temp30_label, S_IRUGO,
1180					applesmc_show_sensor_label, NULL, 29);
1181static SENSOR_DEVICE_ATTR(temp31_label, S_IRUGO,
1182					applesmc_show_sensor_label, NULL, 30);
1183static SENSOR_DEVICE_ATTR(temp32_label, S_IRUGO,
1184					applesmc_show_sensor_label, NULL, 31);
1185static SENSOR_DEVICE_ATTR(temp33_label, S_IRUGO,
1186					applesmc_show_sensor_label, NULL, 32);
1187static SENSOR_DEVICE_ATTR(temp34_label, S_IRUGO,
1188					applesmc_show_sensor_label, NULL, 33);
1189static SENSOR_DEVICE_ATTR(temp35_label, S_IRUGO,
1190					applesmc_show_sensor_label, NULL, 34);
1191static SENSOR_DEVICE_ATTR(temp36_label, S_IRUGO,
1192					applesmc_show_sensor_label, NULL, 35);
1193static SENSOR_DEVICE_ATTR(temp37_label, S_IRUGO,
1194					applesmc_show_sensor_label, NULL, 36);
1195static SENSOR_DEVICE_ATTR(temp38_label, S_IRUGO,
1196					applesmc_show_sensor_label, NULL, 37);
1197static SENSOR_DEVICE_ATTR(temp39_label, S_IRUGO,
1198					applesmc_show_sensor_label, NULL, 38);
1199static SENSOR_DEVICE_ATTR(temp40_label, S_IRUGO,
1200					applesmc_show_sensor_label, NULL, 39);
1201static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1202					applesmc_show_temperature, NULL, 0);
1203static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1204					applesmc_show_temperature, NULL, 1);
1205static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1206					applesmc_show_temperature, NULL, 2);
1207static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1208					applesmc_show_temperature, NULL, 3);
1209static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1210					applesmc_show_temperature, NULL, 4);
1211static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1212					applesmc_show_temperature, NULL, 5);
1213static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1214					applesmc_show_temperature, NULL, 6);
1215static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1216					applesmc_show_temperature, NULL, 7);
1217static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1218					applesmc_show_temperature, NULL, 8);
1219static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1220					applesmc_show_temperature, NULL, 9);
1221static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1222					applesmc_show_temperature, NULL, 10);
1223static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1224					applesmc_show_temperature, NULL, 11);
1225static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1226					applesmc_show_temperature, NULL, 12);
1227static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1228					applesmc_show_temperature, NULL, 13);
1229static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1230					applesmc_show_temperature, NULL, 14);
1231static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1232					applesmc_show_temperature, NULL, 15);
1233static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1234					applesmc_show_temperature, NULL, 16);
1235static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1236					applesmc_show_temperature, NULL, 17);
1237static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1238					applesmc_show_temperature, NULL, 18);
1239static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1240					applesmc_show_temperature, NULL, 19);
1241static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1242					applesmc_show_temperature, NULL, 20);
1243static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1244					applesmc_show_temperature, NULL, 21);
1245static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1246					applesmc_show_temperature, NULL, 22);
1247static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1248					applesmc_show_temperature, NULL, 23);
1249static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1250					applesmc_show_temperature, NULL, 24);
1251static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1252					applesmc_show_temperature, NULL, 25);
1253static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1254					applesmc_show_temperature, NULL, 26);
1255static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1256					applesmc_show_temperature, NULL, 27);
1257static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1258					applesmc_show_temperature, NULL, 28);
1259static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1260					applesmc_show_temperature, NULL, 29);
1261static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1262					applesmc_show_temperature, NULL, 30);
1263static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1264					applesmc_show_temperature, NULL, 31);
1265static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1266					applesmc_show_temperature, NULL, 32);
1267static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1268					applesmc_show_temperature, NULL, 33);
1269static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1270					applesmc_show_temperature, NULL, 34);
1271static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
1272					applesmc_show_temperature, NULL, 35);
1273static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
1274					applesmc_show_temperature, NULL, 36);
1275static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
1276					applesmc_show_temperature, NULL, 37);
1277static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
1278					applesmc_show_temperature, NULL, 38);
1279static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
1280					applesmc_show_temperature, NULL, 39);
1281
1282static struct attribute *label_attributes[] = {
1283	&sensor_dev_attr_temp1_label.dev_attr.attr,
1284	&sensor_dev_attr_temp2_label.dev_attr.attr,
1285	&sensor_dev_attr_temp3_label.dev_attr.attr,
1286	&sensor_dev_attr_temp4_label.dev_attr.attr,
1287	&sensor_dev_attr_temp5_label.dev_attr.attr,
1288	&sensor_dev_attr_temp6_label.dev_attr.attr,
1289	&sensor_dev_attr_temp7_label.dev_attr.attr,
1290	&sensor_dev_attr_temp8_label.dev_attr.attr,
1291	&sensor_dev_attr_temp9_label.dev_attr.attr,
1292	&sensor_dev_attr_temp10_label.dev_attr.attr,
1293	&sensor_dev_attr_temp11_label.dev_attr.attr,
1294	&sensor_dev_attr_temp12_label.dev_attr.attr,
1295	&sensor_dev_attr_temp13_label.dev_attr.attr,
1296	&sensor_dev_attr_temp14_label.dev_attr.attr,
1297	&sensor_dev_attr_temp15_label.dev_attr.attr,
1298	&sensor_dev_attr_temp16_label.dev_attr.attr,
1299	&sensor_dev_attr_temp17_label.dev_attr.attr,
1300	&sensor_dev_attr_temp18_label.dev_attr.attr,
1301	&sensor_dev_attr_temp19_label.dev_attr.attr,
1302	&sensor_dev_attr_temp20_label.dev_attr.attr,
1303	&sensor_dev_attr_temp21_label.dev_attr.attr,
1304	&sensor_dev_attr_temp22_label.dev_attr.attr,
1305	&sensor_dev_attr_temp23_label.dev_attr.attr,
1306	&sensor_dev_attr_temp24_label.dev_attr.attr,
1307	&sensor_dev_attr_temp25_label.dev_attr.attr,
1308	&sensor_dev_attr_temp26_label.dev_attr.attr,
1309	&sensor_dev_attr_temp27_label.dev_attr.attr,
1310	&sensor_dev_attr_temp28_label.dev_attr.attr,
1311	&sensor_dev_attr_temp29_label.dev_attr.attr,
1312	&sensor_dev_attr_temp30_label.dev_attr.attr,
1313	&sensor_dev_attr_temp31_label.dev_attr.attr,
1314	&sensor_dev_attr_temp32_label.dev_attr.attr,
1315	&sensor_dev_attr_temp33_label.dev_attr.attr,
1316	&sensor_dev_attr_temp34_label.dev_attr.attr,
1317	&sensor_dev_attr_temp35_label.dev_attr.attr,
1318	&sensor_dev_attr_temp36_label.dev_attr.attr,
1319	&sensor_dev_attr_temp37_label.dev_attr.attr,
1320	&sensor_dev_attr_temp38_label.dev_attr.attr,
1321	&sensor_dev_attr_temp39_label.dev_attr.attr,
1322	&sensor_dev_attr_temp40_label.dev_attr.attr,
1323	NULL
1324};
1325
1326static struct attribute *temperature_attributes[] = {
1327	&sensor_dev_attr_temp1_input.dev_attr.attr,
1328	&sensor_dev_attr_temp2_input.dev_attr.attr,
1329	&sensor_dev_attr_temp3_input.dev_attr.attr,
1330	&sensor_dev_attr_temp4_input.dev_attr.attr,
1331	&sensor_dev_attr_temp5_input.dev_attr.attr,
1332	&sensor_dev_attr_temp6_input.dev_attr.attr,
1333	&sensor_dev_attr_temp7_input.dev_attr.attr,
1334	&sensor_dev_attr_temp8_input.dev_attr.attr,
1335	&sensor_dev_attr_temp9_input.dev_attr.attr,
1336	&sensor_dev_attr_temp10_input.dev_attr.attr,
1337	&sensor_dev_attr_temp11_input.dev_attr.attr,
1338	&sensor_dev_attr_temp12_input.dev_attr.attr,
1339	&sensor_dev_attr_temp13_input.dev_attr.attr,
1340	&sensor_dev_attr_temp14_input.dev_attr.attr,
1341	&sensor_dev_attr_temp15_input.dev_attr.attr,
1342	&sensor_dev_attr_temp16_input.dev_attr.attr,
1343	&sensor_dev_attr_temp17_input.dev_attr.attr,
1344	&sensor_dev_attr_temp18_input.dev_attr.attr,
1345	&sensor_dev_attr_temp19_input.dev_attr.attr,
1346	&sensor_dev_attr_temp20_input.dev_attr.attr,
1347	&sensor_dev_attr_temp21_input.dev_attr.attr,
1348	&sensor_dev_attr_temp22_input.dev_attr.attr,
1349	&sensor_dev_attr_temp23_input.dev_attr.attr,
1350	&sensor_dev_attr_temp24_input.dev_attr.attr,
1351	&sensor_dev_attr_temp25_input.dev_attr.attr,
1352	&sensor_dev_attr_temp26_input.dev_attr.attr,
1353	&sensor_dev_attr_temp27_input.dev_attr.attr,
1354	&sensor_dev_attr_temp28_input.dev_attr.attr,
1355	&sensor_dev_attr_temp29_input.dev_attr.attr,
1356	&sensor_dev_attr_temp30_input.dev_attr.attr,
1357	&sensor_dev_attr_temp31_input.dev_attr.attr,
1358	&sensor_dev_attr_temp32_input.dev_attr.attr,
1359	&sensor_dev_attr_temp33_input.dev_attr.attr,
1360	&sensor_dev_attr_temp34_input.dev_attr.attr,
1361	&sensor_dev_attr_temp35_input.dev_attr.attr,
1362	&sensor_dev_attr_temp36_input.dev_attr.attr,
1363	&sensor_dev_attr_temp37_input.dev_attr.attr,
1364	&sensor_dev_attr_temp38_input.dev_attr.attr,
1365	&sensor_dev_attr_temp39_input.dev_attr.attr,
1366	&sensor_dev_attr_temp40_input.dev_attr.attr,
1367	NULL
1368};
1369
1370static const struct attribute_group temperature_attributes_group =
1371	{ .attrs = temperature_attributes };
1372
1373static const struct attribute_group label_attributes_group = {
1374	.attrs = label_attributes
1375};
1376
1377/* Module stuff */
1378
1379/*
1380 * applesmc_dmi_match - found a match.  return one, short-circuiting the hunt.
1381 */
1382static int applesmc_dmi_match(const struct dmi_system_id *id)
1383{
1384	int i = 0;
1385	struct dmi_match_data* dmi_data = id->driver_data;
1386	printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1387	applesmc_accelerometer = dmi_data->accelerometer;
1388	printk(KERN_INFO "applesmc:  - Model %s accelerometer\n",
1389				applesmc_accelerometer ? "with" : "without");
1390	applesmc_light = dmi_data->light;
1391	printk(KERN_INFO "applesmc:  - Model %s light sensors and backlight\n",
1392					applesmc_light ? "with" : "without");
1393
1394	applesmc_temperature_set =  dmi_data->temperature_set;
1395	while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1396		i++;
1397	printk(KERN_INFO "applesmc:  - Model with %d temperature sensors\n", i);
1398	return 1;
1399}
1400
1401/* Create accelerometer ressources */
1402static int applesmc_create_accelerometer(void)
1403{
1404	struct input_dev *idev;
1405	int ret;
1406
1407	ret = sysfs_create_group(&pdev->dev.kobj,
1408					&accelerometer_attributes_group);
1409	if (ret)
1410		goto out;
1411
1412	applesmc_idev = input_allocate_polled_device();
1413	if (!applesmc_idev) {
1414		ret = -ENOMEM;
1415		goto out_sysfs;
1416	}
1417
1418	applesmc_idev->poll = applesmc_idev_poll;
1419	applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
1420
1421	/* initial calibrate for the input device */
1422	applesmc_calibrate();
1423
1424	/* initialize the input device */
1425	idev = applesmc_idev->input;
1426	idev->name = "applesmc";
1427	idev->id.bustype = BUS_HOST;
1428	idev->dev.parent = &pdev->dev;
1429	idev->evbit[0] = BIT_MASK(EV_ABS);
1430	input_set_abs_params(idev, ABS_X,
1431			-256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1432	input_set_abs_params(idev, ABS_Y,
1433			-256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1434
1435	ret = input_register_polled_device(applesmc_idev);
1436	if (ret)
1437		goto out_idev;
1438
1439	return 0;
1440
1441out_idev:
1442	input_free_polled_device(applesmc_idev);
1443
1444out_sysfs:
1445	sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1446
1447out:
1448	printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1449	return ret;
1450}
1451
1452/* Release all ressources used by the accelerometer */
1453static void applesmc_release_accelerometer(void)
1454{
1455	input_unregister_polled_device(applesmc_idev);
1456	input_free_polled_device(applesmc_idev);
1457	sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1458}
1459
1460static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1461/* MacBook Pro: accelerometer, backlight and temperature set 0 */
1462	{ .accelerometer = 1, .light = 1, .temperature_set = 0 },
1463/* MacBook2: accelerometer and temperature set 1 */
1464	{ .accelerometer = 1, .light = 0, .temperature_set = 1 },
1465/* MacBook: accelerometer and temperature set 2 */
1466	{ .accelerometer = 1, .light = 0, .temperature_set = 2 },
1467/* MacMini: temperature set 3 */
1468	{ .accelerometer = 0, .light = 0, .temperature_set = 3 },
1469/* MacPro: temperature set 4 */
1470	{ .accelerometer = 0, .light = 0, .temperature_set = 4 },
1471/* iMac: temperature set 5 */
1472	{ .accelerometer = 0, .light = 0, .temperature_set = 5 },
1473/* MacBook3, MacBook4: accelerometer and temperature set 6 */
1474	{ .accelerometer = 1, .light = 0, .temperature_set = 6 },
1475/* MacBook Air: accelerometer, backlight and temperature set 7 */
1476	{ .accelerometer = 1, .light = 1, .temperature_set = 7 },
1477/* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
1478	{ .accelerometer = 1, .light = 1, .temperature_set = 8 },
1479/* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
1480	{ .accelerometer = 1, .light = 1, .temperature_set = 9 },
1481/* iMac 5: light sensor only, temperature set 10 */
1482	{ .accelerometer = 0, .light = 0, .temperature_set = 10 },
1483/* MacBook 5: accelerometer, backlight and temperature set 11 */
1484	{ .accelerometer = 1, .light = 1, .temperature_set = 11 },
1485/* MacBook Pro 5: accelerometer, backlight and temperature set 12 */
1486	{ .accelerometer = 1, .light = 1, .temperature_set = 12 },
1487/* iMac 8: light sensor only, temperature set 13 */
1488	{ .accelerometer = 0, .light = 0, .temperature_set = 13 },
1489/* iMac 6: light sensor only, temperature set 14 */
1490	{ .accelerometer = 0, .light = 0, .temperature_set = 14 },
1491/* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
1492	{ .accelerometer = 1, .light = 1, .temperature_set = 15 },
1493/* MacPro3,1: temperature set 16 */
1494	{ .accelerometer = 0, .light = 0, .temperature_set = 16 },
1495/* iMac 9,1: light sensor only, temperature set 17 */
1496	{ .accelerometer = 0, .light = 0, .temperature_set = 17 },
1497/* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
1498	{ .accelerometer = 1, .light = 1, .temperature_set = 18 },
1499/* MacBook Pro 5,3: accelerometer, backlight and temperature set 19 */
1500	{ .accelerometer = 1, .light = 1, .temperature_set = 19 },
1501/* MacBook Pro 5,4: accelerometer, backlight and temperature set 20 */
1502	{ .accelerometer = 1, .light = 1, .temperature_set = 20 },
1503/* MacBook Pro 6,2: accelerometer, backlight and temperature set 21 */
1504	{ .accelerometer = 1, .light = 1, .temperature_set = 21 },
1505/* MacBook Pro 7,1: accelerometer, backlight and temperature set 22 */
1506	{ .accelerometer = 1, .light = 1, .temperature_set = 22 },
1507/* MacBook Air 3,1: accelerometer, backlight and temperature set 23 */
1508	{ .accelerometer = 0, .light = 0, .temperature_set = 23 },
1509};
1510
1511/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1512 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1513static __initdata struct dmi_system_id applesmc_whitelist[] = {
1514	{ applesmc_dmi_match, "Apple MacBook Air 3", {
1515	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1516	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3") },
1517		&applesmc_dmi_data[23]},
1518	{ applesmc_dmi_match, "Apple MacBook Air 2", {
1519	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1520	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
1521		&applesmc_dmi_data[15]},
1522	{ applesmc_dmi_match, "Apple MacBook Air", {
1523	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1524	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1525		&applesmc_dmi_data[7]},
1526	{ applesmc_dmi_match, "Apple MacBook Pro 7", {
1527	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1528	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro7") },
1529		&applesmc_dmi_data[22]},
1530	{ applesmc_dmi_match, "Apple MacBook Pro 5,4", {
1531	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1532	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4") },
1533		&applesmc_dmi_data[20]},
1534	{ applesmc_dmi_match, "Apple MacBook Pro 5,3", {
1535	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1536	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3") },
1537		&applesmc_dmi_data[19]},
1538	{ applesmc_dmi_match, "Apple MacBook Pro 6", {
1539	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1540	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6") },
1541		&applesmc_dmi_data[21]},
1542	{ applesmc_dmi_match, "Apple MacBook Pro 5", {
1543	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1544	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1545		&applesmc_dmi_data[12]},
1546	{ applesmc_dmi_match, "Apple MacBook Pro 4", {
1547	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1548	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1549		&applesmc_dmi_data[8]},
1550	{ applesmc_dmi_match, "Apple MacBook Pro 3", {
1551	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1552	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1553		&applesmc_dmi_data[9]},
1554	{ applesmc_dmi_match, "Apple MacBook Pro 2,2", {
1555	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
1556	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
1557		&applesmc_dmi_data[18]},
1558	{ applesmc_dmi_match, "Apple MacBook Pro", {
1559	  DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1560	  DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1561		&applesmc_dmi_data[0]},
1562	{ applesmc_dmi_match, "Apple MacBook (v2)", {
1563	  DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1564	  DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1565		&applesmc_dmi_data[1]},
1566	{ applesmc_dmi_match, "Apple MacBook (v3)", {
1567	  DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1568	  DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1569		&applesmc_dmi_data[6]},
1570	{ applesmc_dmi_match, "Apple MacBook 4", {
1571	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1572	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1573		&applesmc_dmi_data[6]},
1574	{ applesmc_dmi_match, "Apple MacBook 5", {
1575	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1576	  DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") },
1577		&applesmc_dmi_data[11]},
1578	{ applesmc_dmi_match, "Apple MacBook", {
1579	  DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1580	  DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1581		&applesmc_dmi_data[2]},
1582	{ applesmc_dmi_match, "Apple Macmini", {
1583	  DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1584	  DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1585		&applesmc_dmi_data[3]},
1586	{ applesmc_dmi_match, "Apple MacPro2", {
1587	  DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1588	  DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1589		&applesmc_dmi_data[4]},
1590	{ applesmc_dmi_match, "Apple MacPro3", {
1591	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1592	  DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") },
1593		&applesmc_dmi_data[16]},
1594	{ applesmc_dmi_match, "Apple MacPro", {
1595	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1596	  DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1597		&applesmc_dmi_data[4]},
1598	{ applesmc_dmi_match, "Apple iMac 9,1", {
1599	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
1600	  DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
1601		&applesmc_dmi_data[17]},
1602	{ applesmc_dmi_match, "Apple iMac 8", {
1603	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1604	  DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1605		&applesmc_dmi_data[13]},
1606	{ applesmc_dmi_match, "Apple iMac 6", {
1607	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1608	  DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
1609		&applesmc_dmi_data[14]},
1610	{ applesmc_dmi_match, "Apple iMac 5", {
1611	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1612	  DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1613		&applesmc_dmi_data[10]},
1614	{ applesmc_dmi_match, "Apple iMac", {
1615	  DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1616	  DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1617		&applesmc_dmi_data[5]},
1618	{ .ident = NULL }
1619};
1620
1621static int __init applesmc_init(void)
1622{
1623	int ret;
1624	int count;
1625	int i;
1626
1627	if (!dmi_check_system(applesmc_whitelist)) {
1628		printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1629		ret = -ENODEV;
1630		goto out;
1631	}
1632
1633	if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1634								"applesmc")) {
1635		ret = -ENXIO;
1636		goto out;
1637	}
1638
1639	ret = platform_driver_register(&applesmc_driver);
1640	if (ret)
1641		goto out_region;
1642
1643	pdev = platform_device_register_simple("applesmc", APPLESMC_DATA_PORT,
1644					       NULL, 0);
1645	if (IS_ERR(pdev)) {
1646		ret = PTR_ERR(pdev);
1647		goto out_driver;
1648	}
1649
1650	ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
1651	if (ret)
1652		goto out_device;
1653
1654	/* Create key enumeration sysfs files */
1655	ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1656	if (ret)
1657		goto out_name;
1658
1659	/* create fan files */
1660	count = applesmc_get_fan_count();
1661	if (count < 0)
1662		printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1663	else
1664		printk(KERN_INFO "applesmc: %d fans found.\n", count);
1665
1666	if (count > 4) {
1667		count = 4;
1668		printk(KERN_WARNING "applesmc: More than 4 fans found,"
1669		       " but at most 4 fans are supported"
1670		       " by the driver.\n");
1671	}
1672
1673	while (fans_handled < count) {
1674		ret = sysfs_create_group(&pdev->dev.kobj,
1675					 &fan_attribute_groups[fans_handled]);
1676		if (ret)
1677			goto out_fans;
1678		fans_handled++;
1679	}
1680
1681	for (i = 0;
1682	     temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1683	     i++) {
1684		if (temperature_attributes[i] == NULL ||
1685		    label_attributes[i] == NULL) {
1686			printk(KERN_ERR "applesmc: More temperature sensors "
1687				"in temperature_sensors_sets (at least %i)"
1688				"than available sysfs files in "
1689				"temperature_attributes (%i), please report "
1690				"this bug.\n", i, i-1);
1691			goto out_temperature;
1692		}
1693		ret = sysfs_create_file(&pdev->dev.kobj,
1694						temperature_attributes[i]);
1695		if (ret)
1696			goto out_temperature;
1697		ret = sysfs_create_file(&pdev->dev.kobj,
1698						label_attributes[i]);
1699		if (ret)
1700			goto out_temperature;
1701	}
1702
1703	if (applesmc_accelerometer) {
1704		ret = applesmc_create_accelerometer();
1705		if (ret)
1706			goto out_temperature;
1707	}
1708
1709	if (applesmc_light) {
1710		/* Add light sensor file */
1711		ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1712		if (ret)
1713			goto out_accelerometer;
1714
1715		/* Create the workqueue */
1716		applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1717		if (!applesmc_led_wq) {
1718			ret = -ENOMEM;
1719			goto out_light_sysfs;
1720		}
1721
1722		/* register as a led device */
1723		ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1724		if (ret < 0)
1725			goto out_light_wq;
1726	}
1727
1728	hwmon_dev = hwmon_device_register(&pdev->dev);
1729	if (IS_ERR(hwmon_dev)) {
1730		ret = PTR_ERR(hwmon_dev);
1731		goto out_light_ledclass;
1732	}
1733
1734	printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1735
1736	return 0;
1737
1738out_light_ledclass:
1739	if (applesmc_light)
1740		led_classdev_unregister(&applesmc_backlight);
1741out_light_wq:
1742	if (applesmc_light)
1743		destroy_workqueue(applesmc_led_wq);
1744out_light_sysfs:
1745	if (applesmc_light)
1746		sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1747out_accelerometer:
1748	if (applesmc_accelerometer)
1749		applesmc_release_accelerometer();
1750out_temperature:
1751	sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group);
1752	sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1753out_fans:
1754	while (fans_handled)
1755		sysfs_remove_group(&pdev->dev.kobj,
1756				   &fan_attribute_groups[--fans_handled]);
1757	sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1758out_name:
1759	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1760out_device:
1761	platform_device_unregister(pdev);
1762out_driver:
1763	platform_driver_unregister(&applesmc_driver);
1764out_region:
1765	release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1766out:
1767	printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1768	return ret;
1769}
1770
1771static void __exit applesmc_exit(void)
1772{
1773	hwmon_device_unregister(hwmon_dev);
1774	if (applesmc_light) {
1775		led_classdev_unregister(&applesmc_backlight);
1776		destroy_workqueue(applesmc_led_wq);
1777		sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1778	}
1779	if (applesmc_accelerometer)
1780		applesmc_release_accelerometer();
1781	sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group);
1782	sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1783	while (fans_handled)
1784		sysfs_remove_group(&pdev->dev.kobj,
1785				   &fan_attribute_groups[--fans_handled]);
1786	sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1787	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1788	platform_device_unregister(pdev);
1789	platform_driver_unregister(&applesmc_driver);
1790	release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1791
1792	printk(KERN_INFO "applesmc: driver unloaded.\n");
1793}
1794
1795module_init(applesmc_init);
1796module_exit(applesmc_exit);
1797
1798MODULE_AUTHOR("Nicolas Boichat");
1799MODULE_DESCRIPTION("Apple SMC");
1800MODULE_LICENSE("GPL v2");
1801MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);
1802