aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/applesmc.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/hwmon/applesmc.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/hwmon/applesmc.c')
-rw-r--r--drivers/hwmon/applesmc.c1633
1 files changed, 575 insertions, 1058 deletions
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index b6598aa557a0..4c0743660e9c 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -4,6 +4,7 @@
4 * computers. 4 * computers.
5 * 5 *
6 * Copyright (C) 2007 Nicolas Boichat <nicolas@boichat.ch> 6 * Copyright (C) 2007 Nicolas Boichat <nicolas@boichat.ch>
7 * Copyright (C) 2010 Henrik Rydberg <rydberg@euromail.se>
7 * 8 *
8 * Based on hdaps.c driver: 9 * Based on hdaps.c driver:
9 * Copyright (C) 2005 Robert Love <rml@novell.com> 10 * Copyright (C) 2005 Robert Love <rml@novell.com>
@@ -26,10 +27,13 @@
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27 */ 28 */
28 29
30#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31
29#include <linux/delay.h> 32#include <linux/delay.h>
30#include <linux/platform_device.h> 33#include <linux/platform_device.h>
31#include <linux/input-polldev.h> 34#include <linux/input-polldev.h>
32#include <linux/kernel.h> 35#include <linux/kernel.h>
36#include <linux/slab.h>
33#include <linux/module.h> 37#include <linux/module.h>
34#include <linux/timer.h> 38#include <linux/timer.h>
35#include <linux/dmi.h> 39#include <linux/dmi.h>
@@ -49,6 +53,7 @@
49 53
50#define APPLESMC_MAX_DATA_LENGTH 32 54#define APPLESMC_MAX_DATA_LENGTH 32
51 55
56/* wait up to 32 ms for a status change. */
52#define APPLESMC_MIN_WAIT 0x0040 57#define APPLESMC_MIN_WAIT 0x0040
53#define APPLESMC_MAX_WAIT 0x8000 58#define APPLESMC_MAX_WAIT 0x8000
54 59
@@ -73,104 +78,15 @@
73 78
74#define FANS_COUNT "FNum" /* r-o ui8 */ 79#define FANS_COUNT "FNum" /* r-o ui8 */
75#define FANS_MANUAL "FS! " /* r-w ui16 */ 80#define FANS_MANUAL "FS! " /* r-w ui16 */
76#define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */ 81#define FAN_ID_FMT "F%dID" /* r-o char[16] */
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};
166 82
167/* List of keys used to read/write fan speeds */ 83/* List of keys used to read/write fan speeds */
168static const char* fan_speed_keys[] = { 84static const char *const fan_speed_fmt[] = {
169 FAN_ACTUAL_SPEED, 85 "F%dAc", /* actual speed */
170 FAN_MIN_SPEED, 86 "F%dMn", /* minimum speed (rw) */
171 FAN_MAX_SPEED, 87 "F%dMx", /* maximum speed */
172 FAN_SAFE_SPEED, 88 "F%dSf", /* safe speed - not all models */
173 FAN_TARGET_SPEED 89 "F%dTg", /* target speed (manual: rw) */
174}; 90};
175 91
176#define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */ 92#define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
@@ -184,14 +100,48 @@ static const char* fan_speed_keys[] = {
184#define SENSOR_Y 1 100#define SENSOR_Y 1
185#define SENSOR_Z 2 101#define SENSOR_Z 2
186 102
187/* Structure to be passed to DMI_MATCH function */ 103#define to_index(attr) (to_sensor_dev_attr(attr)->index & 0xffff)
188struct dmi_match_data { 104#define to_option(attr) (to_sensor_dev_attr(attr)->index >> 16)
189/* Indicates whether this computer has an accelerometer. */ 105
190 int accelerometer; 106/* Dynamic device node attributes */
191/* Indicates whether this computer has light sensors and keyboard backlight. */ 107struct applesmc_dev_attr {
192 int light; 108 struct sensor_device_attribute sda; /* hwmon attributes */
193/* Indicates which temperature sensors set to use. */ 109 char name[32]; /* room for node file name */
194 int temperature_set; 110};
111
112/* Dynamic device node group */
113struct applesmc_node_group {
114 char *format; /* format string */
115 void *show; /* show function */
116 void *store; /* store function */
117 int option; /* function argument */
118 struct applesmc_dev_attr *nodes; /* dynamic node array */
119};
120
121/* AppleSMC entry - cached register information */
122struct applesmc_entry {
123 char key[5]; /* four-letter key code */
124 u8 valid; /* set when entry is successfully read once */
125 u8 len; /* bounded by APPLESMC_MAX_DATA_LENGTH */
126 char type[5]; /* four-letter type code */
127 u8 flags; /* 0x10: func; 0x40: write; 0x80: read */
128};
129
130/* Register lookup and registers common to all SMCs */
131static struct applesmc_registers {
132 struct mutex mutex; /* register read/write mutex */
133 unsigned int key_count; /* number of SMC registers */
134 unsigned int fan_count; /* number of fans */
135 unsigned int temp_count; /* number of temperature registers */
136 unsigned int temp_begin; /* temperature lower index bound */
137 unsigned int temp_end; /* temperature upper index bound */
138 int num_light_sensors; /* number of light sensors */
139 bool has_accelerometer; /* has motion sensor */
140 bool has_key_backlight; /* has keyboard backlight */
141 bool init_complete; /* true when fully initialized */
142 struct applesmc_entry *cache; /* cached key entries */
143} smcreg = {
144 .mutex = __MUTEX_INITIALIZER(smcreg.mutex),
195}; 145};
196 146
197static const int debug; 147static const int debug;
@@ -203,20 +153,6 @@ static u8 backlight_state[2];
203static struct device *hwmon_dev; 153static struct device *hwmon_dev;
204static struct input_polled_dev *applesmc_idev; 154static struct input_polled_dev *applesmc_idev;
205 155
206/* Indicates whether this computer has an accelerometer. */
207static unsigned int applesmc_accelerometer;
208
209/* Indicates whether this computer has light sensors and keyboard backlight. */
210static unsigned int applesmc_light;
211
212/* The number of fans handled by the driver */
213static unsigned int fans_handled;
214
215/* Indicates which temperature sensors set to use. */
216static unsigned int applesmc_temperature_set;
217
218static DEFINE_MUTEX(applesmc_lock);
219
220/* 156/*
221 * Last index written to key_at_index sysfs file, and value to use for all other 157 * Last index written to key_at_index sysfs file, and value to use for all other
222 * key_at_index_* sysfs files. 158 * key_at_index_* sysfs files.
@@ -238,18 +174,10 @@ static int __wait_status(u8 val)
238 174
239 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { 175 for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
240 udelay(us); 176 udelay(us);
241 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) { 177 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val)
242 if (debug)
243 printk(KERN_DEBUG
244 "Waited %d us for status %x\n",
245 2 * us - APPLESMC_MIN_WAIT, val);
246 return 0; 178 return 0;
247 }
248 } 179 }
249 180
250 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
251 val, inb(APPLESMC_CMD_PORT));
252
253 return -EIO; 181 return -EIO;
254} 182}
255 183
@@ -267,159 +195,242 @@ static int send_command(u8 cmd)
267 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c) 195 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
268 return 0; 196 return 0;
269 } 197 }
270 printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
271 cmd, inb(APPLESMC_CMD_PORT));
272 return -EIO; 198 return -EIO;
273} 199}
274 200
275/* 201static int send_argument(const char *key)
276 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
277 * Returns zero on success or a negative error on failure. Callers must
278 * hold applesmc_lock.
279 */
280static int applesmc_read_key(const char* key, u8* buffer, u8 len)
281{ 202{
282 int i; 203 int i;
283 204
284 if (len > APPLESMC_MAX_DATA_LENGTH) {
285 printk(KERN_ERR "applesmc_read_key: cannot read more than "
286 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
287 return -EINVAL;
288 }
289
290 if (send_command(APPLESMC_READ_CMD))
291 return -EIO;
292
293 for (i = 0; i < 4; i++) { 205 for (i = 0; i < 4; i++) {
294 outb(key[i], APPLESMC_DATA_PORT); 206 outb(key[i], APPLESMC_DATA_PORT);
295 if (__wait_status(0x04)) 207 if (__wait_status(0x04))
296 return -EIO; 208 return -EIO;
297 } 209 }
298 if (debug) 210 return 0;
299 printk(KERN_DEBUG "<%s", key); 211}
212
213static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
214{
215 int i;
216
217 if (send_command(cmd) || send_argument(key)) {
218 pr_warn("%s: read arg fail\n", key);
219 return -EIO;
220 }
300 221
301 outb(len, APPLESMC_DATA_PORT); 222 outb(len, APPLESMC_DATA_PORT);
302 if (debug)
303 printk(KERN_DEBUG ">%x", len);
304 223
305 for (i = 0; i < len; i++) { 224 for (i = 0; i < len; i++) {
306 if (__wait_status(0x05)) 225 if (__wait_status(0x05)) {
226 pr_warn("%s: read data fail\n", key);
307 return -EIO; 227 return -EIO;
228 }
308 buffer[i] = inb(APPLESMC_DATA_PORT); 229 buffer[i] = inb(APPLESMC_DATA_PORT);
309 if (debug)
310 printk(KERN_DEBUG "<%x", buffer[i]);
311 } 230 }
312 if (debug)
313 printk(KERN_DEBUG "\n");
314 231
315 return 0; 232 return 0;
316} 233}
317 234
318/* 235static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
319 * applesmc_write_key - writes len bytes from buffer to a given key.
320 * Returns zero on success or a negative error on failure. Callers must
321 * hold applesmc_lock.
322 */
323static int applesmc_write_key(const char* key, u8* buffer, u8 len)
324{ 236{
325 int i; 237 int i;
326 238
327 if (len > APPLESMC_MAX_DATA_LENGTH) { 239 if (send_command(cmd) || send_argument(key)) {
328 printk(KERN_ERR "applesmc_write_key: cannot write more than " 240 pr_warn("%s: write arg fail\n", key);
329 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
330 return -EINVAL;
331 }
332
333 if (send_command(APPLESMC_WRITE_CMD))
334 return -EIO; 241 return -EIO;
335
336 for (i = 0; i < 4; i++) {
337 outb(key[i], APPLESMC_DATA_PORT);
338 if (__wait_status(0x04))
339 return -EIO;
340 } 242 }
341 243
342 outb(len, APPLESMC_DATA_PORT); 244 outb(len, APPLESMC_DATA_PORT);
343 245
344 for (i = 0; i < len; i++) { 246 for (i = 0; i < len; i++) {
345 if (__wait_status(0x04)) 247 if (__wait_status(0x04)) {
248 pr_warn("%s: write data fail\n", key);
346 return -EIO; 249 return -EIO;
250 }
347 outb(buffer[i], APPLESMC_DATA_PORT); 251 outb(buffer[i], APPLESMC_DATA_PORT);
348 } 252 }
349 253
350 return 0; 254 return 0;
351} 255}
352 256
257static int read_register_count(unsigned int *count)
258{
259 __be32 be;
260 int ret;
261
262 ret = read_smc(APPLESMC_READ_CMD, KEY_COUNT_KEY, (u8 *)&be, 4);
263 if (ret)
264 return ret;
265
266 *count = be32_to_cpu(be);
267 return 0;
268}
269
353/* 270/*
354 * applesmc_get_key_at_index - get key at index, and put the result in key 271 * Serialized I/O
355 * (char[6]). Returns zero on success or a negative error on failure. Callers 272 *
356 * must hold applesmc_lock. 273 * Returns zero on success or a negative error on failure.
274 * All functions below are concurrency safe - callers should NOT hold lock.
357 */ 275 */
358static int applesmc_get_key_at_index(int index, char* key) 276
277static int applesmc_read_entry(const struct applesmc_entry *entry,
278 u8 *buf, u8 len)
359{ 279{
360 int i; 280 int ret;
361 u8 readkey[4];
362 readkey[0] = index >> 24;
363 readkey[1] = index >> 16;
364 readkey[2] = index >> 8;
365 readkey[3] = index;
366 281
367 if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD)) 282 if (entry->len != len)
368 return -EIO; 283 return -EINVAL;
284 mutex_lock(&smcreg.mutex);
285 ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len);
286 mutex_unlock(&smcreg.mutex);
369 287
370 for (i = 0; i < 4; i++) { 288 return ret;
371 outb(readkey[i], APPLESMC_DATA_PORT); 289}
372 if (__wait_status(0x04)) 290
373 return -EIO; 291static int applesmc_write_entry(const struct applesmc_entry *entry,
292 const u8 *buf, u8 len)
293{
294 int ret;
295
296 if (entry->len != len)
297 return -EINVAL;
298 mutex_lock(&smcreg.mutex);
299 ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len);
300 mutex_unlock(&smcreg.mutex);
301 return ret;
302}
303
304static const struct applesmc_entry *applesmc_get_entry_by_index(int index)
305{
306 struct applesmc_entry *cache = &smcreg.cache[index];
307 u8 key[4], info[6];
308 __be32 be;
309 int ret = 0;
310
311 if (cache->valid)
312 return cache;
313
314 mutex_lock(&smcreg.mutex);
315
316 if (cache->valid)
317 goto out;
318 be = cpu_to_be32(index);
319 ret = read_smc(APPLESMC_GET_KEY_BY_INDEX_CMD, (u8 *)&be, key, 4);
320 if (ret)
321 goto out;
322 ret = read_smc(APPLESMC_GET_KEY_TYPE_CMD, key, info, 6);
323 if (ret)
324 goto out;
325
326 memcpy(cache->key, key, 4);
327 cache->len = info[0];
328 memcpy(cache->type, &info[1], 4);
329 cache->flags = info[5];
330 cache->valid = 1;
331
332out:
333 mutex_unlock(&smcreg.mutex);
334 if (ret)
335 return ERR_PTR(ret);
336 return cache;
337}
338
339static int applesmc_get_lower_bound(unsigned int *lo, const char *key)
340{
341 int begin = 0, end = smcreg.key_count;
342 const struct applesmc_entry *entry;
343
344 while (begin != end) {
345 int middle = begin + (end - begin) / 2;
346 entry = applesmc_get_entry_by_index(middle);
347 if (IS_ERR(entry))
348 return PTR_ERR(entry);
349 if (strcmp(entry->key, key) < 0)
350 begin = middle + 1;
351 else
352 end = middle;
374 } 353 }
375 354
376 outb(4, APPLESMC_DATA_PORT); 355 *lo = begin;
356 return 0;
357}
377 358
378 for (i = 0; i < 4; i++) { 359static int applesmc_get_upper_bound(unsigned int *hi, const char *key)
379 if (__wait_status(0x05)) 360{
380 return -EIO; 361 int begin = 0, end = smcreg.key_count;
381 key[i] = inb(APPLESMC_DATA_PORT); 362 const struct applesmc_entry *entry;
363
364 while (begin != end) {
365 int middle = begin + (end - begin) / 2;
366 entry = applesmc_get_entry_by_index(middle);
367 if (IS_ERR(entry))
368 return PTR_ERR(entry);
369 if (strcmp(key, entry->key) < 0)
370 end = middle;
371 else
372 begin = middle + 1;
382 } 373 }
383 key[4] = 0;
384 374
375 *hi = begin;
385 return 0; 376 return 0;
386} 377}
387 378
388/* 379static const struct applesmc_entry *applesmc_get_entry_by_key(const char *key)
389 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
390 * Returns zero on success or a negative error on failure. Callers must
391 * hold applesmc_lock.
392 */
393static int applesmc_get_key_type(char* key, char* type)
394{ 380{
395 int i; 381 int begin, end;
382 int ret;
396 383
397 if (send_command(APPLESMC_GET_KEY_TYPE_CMD)) 384 ret = applesmc_get_lower_bound(&begin, key);
398 return -EIO; 385 if (ret)
386 return ERR_PTR(ret);
387 ret = applesmc_get_upper_bound(&end, key);
388 if (ret)
389 return ERR_PTR(ret);
390 if (end - begin != 1)
391 return ERR_PTR(-EINVAL);
399 392
400 for (i = 0; i < 4; i++) { 393 return applesmc_get_entry_by_index(begin);
401 outb(key[i], APPLESMC_DATA_PORT); 394}
402 if (__wait_status(0x04))
403 return -EIO;
404 }
405 395
406 outb(6, APPLESMC_DATA_PORT); 396static int applesmc_read_key(const char *key, u8 *buffer, u8 len)
397{
398 const struct applesmc_entry *entry;
407 399
408 for (i = 0; i < 6; i++) { 400 entry = applesmc_get_entry_by_key(key);
409 if (__wait_status(0x05)) 401 if (IS_ERR(entry))
410 return -EIO; 402 return PTR_ERR(entry);
411 type[i] = inb(APPLESMC_DATA_PORT); 403
412 } 404 return applesmc_read_entry(entry, buffer, len);
413 type[5] = 0; 405}
406
407static int applesmc_write_key(const char *key, const u8 *buffer, u8 len)
408{
409 const struct applesmc_entry *entry;
414 410
411 entry = applesmc_get_entry_by_key(key);
412 if (IS_ERR(entry))
413 return PTR_ERR(entry);
414
415 return applesmc_write_entry(entry, buffer, len);
416}
417
418static int applesmc_has_key(const char *key, bool *value)
419{
420 const struct applesmc_entry *entry;
421
422 entry = applesmc_get_entry_by_key(key);
423 if (IS_ERR(entry) && PTR_ERR(entry) != -EINVAL)
424 return PTR_ERR(entry);
425
426 *value = !IS_ERR(entry);
415 return 0; 427 return 0;
416} 428}
417 429
418/* 430/*
419 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must 431 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z).
420 * hold applesmc_lock.
421 */ 432 */
422static int applesmc_read_motion_sensor(int index, s16* value) 433static int applesmc_read_motion_sensor(int index, s16 *value)
423{ 434{
424 u8 buffer[2]; 435 u8 buffer[2];
425 int ret; 436 int ret;
@@ -444,69 +455,120 @@ static int applesmc_read_motion_sensor(int index, s16* value)
444} 455}
445 456
446/* 457/*
447 * applesmc_device_init - initialize the accelerometer. Returns zero on success 458 * applesmc_device_init - initialize the accelerometer. Can sleep.
448 * and negative error code on failure. Can sleep.
449 */ 459 */
450static int applesmc_device_init(void) 460static void applesmc_device_init(void)
451{ 461{
452 int total, ret = -ENXIO; 462 int total;
453 u8 buffer[2]; 463 u8 buffer[2];
454 464
455 if (!applesmc_accelerometer) 465 if (!smcreg.has_accelerometer)
456 return 0; 466 return;
457
458 mutex_lock(&applesmc_lock);
459 467
460 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { 468 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
461 if (debug)
462 printk(KERN_DEBUG "applesmc try %d\n", total);
463 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) && 469 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
464 (buffer[0] != 0x00 || buffer[1] != 0x00)) { 470 (buffer[0] != 0x00 || buffer[1] != 0x00))
465 if (total == INIT_TIMEOUT_MSECS) { 471 return;
466 printk(KERN_DEBUG "applesmc: device has"
467 " already been initialized"
468 " (0x%02x, 0x%02x).\n",
469 buffer[0], buffer[1]);
470 } else {
471 printk(KERN_DEBUG "applesmc: device"
472 " successfully initialized"
473 " (0x%02x, 0x%02x).\n",
474 buffer[0], buffer[1]);
475 }
476 ret = 0;
477 goto out;
478 }
479 buffer[0] = 0xe0; 472 buffer[0] = 0xe0;
480 buffer[1] = 0x00; 473 buffer[1] = 0x00;
481 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2); 474 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
482 msleep(INIT_WAIT_MSECS); 475 msleep(INIT_WAIT_MSECS);
483 } 476 }
484 477
485 printk(KERN_WARNING "applesmc: failed to init the device\n"); 478 pr_warn("failed to init the device\n");
486
487out:
488 mutex_unlock(&applesmc_lock);
489 return ret;
490} 479}
491 480
492/* 481/*
493 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold 482 * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent.
494 * applesmc_lock.
495 */ 483 */
496static int applesmc_get_fan_count(void) 484static int applesmc_init_smcreg_try(void)
497{ 485{
486 struct applesmc_registers *s = &smcreg;
487 bool left_light_sensor, right_light_sensor;
488 u8 tmp[1];
498 int ret; 489 int ret;
499 u8 buffer[1];
500 490
501 mutex_lock(&applesmc_lock); 491 if (s->init_complete)
492 return 0;
502 493
503 ret = applesmc_read_key(FANS_COUNT, buffer, 1); 494 ret = read_register_count(&s->key_count);
495 if (ret)
496 return ret;
497
498 if (!s->cache)
499 s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL);
500 if (!s->cache)
501 return -ENOMEM;
504 502
505 mutex_unlock(&applesmc_lock); 503 ret = applesmc_read_key(FANS_COUNT, tmp, 1);
506 if (ret) 504 if (ret)
507 return ret; 505 return ret;
508 else 506 s->fan_count = tmp[0];
509 return buffer[0]; 507
508 ret = applesmc_get_lower_bound(&s->temp_begin, "T");
509 if (ret)
510 return ret;
511 ret = applesmc_get_lower_bound(&s->temp_end, "U");
512 if (ret)
513 return ret;
514 s->temp_count = s->temp_end - s->temp_begin;
515
516 ret = applesmc_has_key(LIGHT_SENSOR_LEFT_KEY, &left_light_sensor);
517 if (ret)
518 return ret;
519 ret = applesmc_has_key(LIGHT_SENSOR_RIGHT_KEY, &right_light_sensor);
520 if (ret)
521 return ret;
522 ret = applesmc_has_key(MOTION_SENSOR_KEY, &s->has_accelerometer);
523 if (ret)
524 return ret;
525 ret = applesmc_has_key(BACKLIGHT_KEY, &s->has_key_backlight);
526 if (ret)
527 return ret;
528
529 s->num_light_sensors = left_light_sensor + right_light_sensor;
530 s->init_complete = true;
531
532 pr_info("key=%d fan=%d temp=%d acc=%d lux=%d kbd=%d\n",
533 s->key_count, s->fan_count, s->temp_count,
534 s->has_accelerometer,
535 s->num_light_sensors,
536 s->has_key_backlight);
537
538 return 0;
539}
540
541/*
542 * applesmc_init_smcreg - Initialize register cache.
543 *
544 * Retries until initialization is successful, or the operation times out.
545 *
546 */
547static int applesmc_init_smcreg(void)
548{
549 int ms, ret;
550
551 for (ms = 0; ms < INIT_TIMEOUT_MSECS; ms += INIT_WAIT_MSECS) {
552 ret = applesmc_init_smcreg_try();
553 if (!ret) {
554 if (ms)
555 pr_info("init_smcreg() took %d ms\n", ms);
556 return 0;
557 }
558 msleep(INIT_WAIT_MSECS);
559 }
560
561 kfree(smcreg.cache);
562 smcreg.cache = NULL;
563
564 return ret;
565}
566
567static void applesmc_destroy_smcreg(void)
568{
569 kfree(smcreg.cache);
570 smcreg.cache = NULL;
571 smcreg.init_complete = false;
510} 572}
511 573
512/* Device model stuff */ 574/* Device model stuff */
@@ -514,30 +576,27 @@ static int applesmc_probe(struct platform_device *dev)
514{ 576{
515 int ret; 577 int ret;
516 578
517 ret = applesmc_device_init(); 579 ret = applesmc_init_smcreg();
518 if (ret) 580 if (ret)
519 return ret; 581 return ret;
520 582
521 printk(KERN_INFO "applesmc: device successfully initialized.\n"); 583 applesmc_device_init();
584
522 return 0; 585 return 0;
523} 586}
524 587
525/* Synchronize device with memorized backlight state */ 588/* Synchronize device with memorized backlight state */
526static int applesmc_pm_resume(struct device *dev) 589static int applesmc_pm_resume(struct device *dev)
527{ 590{
528 mutex_lock(&applesmc_lock); 591 if (smcreg.has_key_backlight)
529 if (applesmc_light)
530 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); 592 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
531 mutex_unlock(&applesmc_lock);
532 return 0; 593 return 0;
533} 594}
534 595
535/* Reinitialize device on resume from hibernation */ 596/* Reinitialize device on resume from hibernation */
536static int applesmc_pm_restore(struct device *dev) 597static int applesmc_pm_restore(struct device *dev)
537{ 598{
538 int ret = applesmc_device_init(); 599 applesmc_device_init();
539 if (ret)
540 return ret;
541 return applesmc_pm_resume(dev); 600 return applesmc_pm_resume(dev);
542} 601}
543 602
@@ -571,20 +630,15 @@ static void applesmc_idev_poll(struct input_polled_dev *dev)
571 struct input_dev *idev = dev->input; 630 struct input_dev *idev = dev->input;
572 s16 x, y; 631 s16 x, y;
573 632
574 mutex_lock(&applesmc_lock);
575
576 if (applesmc_read_motion_sensor(SENSOR_X, &x)) 633 if (applesmc_read_motion_sensor(SENSOR_X, &x))
577 goto out; 634 return;
578 if (applesmc_read_motion_sensor(SENSOR_Y, &y)) 635 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
579 goto out; 636 return;
580 637
581 x = -x; 638 x = -x;
582 input_report_abs(idev, ABS_X, x - rest_x); 639 input_report_abs(idev, ABS_X, x - rest_x);
583 input_report_abs(idev, ABS_Y, y - rest_y); 640 input_report_abs(idev, ABS_Y, y - rest_y);
584 input_sync(idev); 641 input_sync(idev);
585
586out:
587 mutex_unlock(&applesmc_lock);
588} 642}
589 643
590/* Sysfs Files */ 644/* Sysfs Files */
@@ -601,8 +655,6 @@ static ssize_t applesmc_position_show(struct device *dev,
601 int ret; 655 int ret;
602 s16 x, y, z; 656 s16 x, y, z;
603 657
604 mutex_lock(&applesmc_lock);
605
606 ret = applesmc_read_motion_sensor(SENSOR_X, &x); 658 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
607 if (ret) 659 if (ret)
608 goto out; 660 goto out;
@@ -614,7 +666,6 @@ static ssize_t applesmc_position_show(struct device *dev,
614 goto out; 666 goto out;
615 667
616out: 668out:
617 mutex_unlock(&applesmc_lock);
618 if (ret) 669 if (ret)
619 return ret; 670 return ret;
620 else 671 else
@@ -624,20 +675,20 @@ out:
624static ssize_t applesmc_light_show(struct device *dev, 675static ssize_t applesmc_light_show(struct device *dev,
625 struct device_attribute *attr, char *sysfsbuf) 676 struct device_attribute *attr, char *sysfsbuf)
626{ 677{
678 const struct applesmc_entry *entry;
627 static int data_length; 679 static int data_length;
628 int ret; 680 int ret;
629 u8 left = 0, right = 0; 681 u8 left = 0, right = 0;
630 u8 buffer[10], query[6]; 682 u8 buffer[10];
631
632 mutex_lock(&applesmc_lock);
633 683
634 if (!data_length) { 684 if (!data_length) {
635 ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query); 685 entry = applesmc_get_entry_by_key(LIGHT_SENSOR_LEFT_KEY);
636 if (ret) 686 if (IS_ERR(entry))
637 goto out; 687 return PTR_ERR(entry);
638 data_length = clamp_val(query[0], 0, 10); 688 if (entry->len > 10)
639 printk(KERN_INFO "applesmc: light sensor data length set to " 689 return -ENXIO;
640 "%d\n", data_length); 690 data_length = entry->len;
691 pr_info("light sensor data length set to %d\n", data_length);
641 } 692 }
642 693
643 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length); 694 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
@@ -653,7 +704,6 @@ static ssize_t applesmc_light_show(struct device *dev,
653 right = buffer[2]; 704 right = buffer[2];
654 705
655out: 706out:
656 mutex_unlock(&applesmc_lock);
657 if (ret) 707 if (ret)
658 return ret; 708 return ret;
659 else 709 else
@@ -664,36 +714,44 @@ out:
664static ssize_t applesmc_show_sensor_label(struct device *dev, 714static ssize_t applesmc_show_sensor_label(struct device *dev,
665 struct device_attribute *devattr, char *sysfsbuf) 715 struct device_attribute *devattr, char *sysfsbuf)
666{ 716{
667 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 717 int index = smcreg.temp_begin + to_index(devattr);
668 const char *key = 718 const struct applesmc_entry *entry;
669 temperature_sensors_sets[applesmc_temperature_set][attr->index]; 719
720 entry = applesmc_get_entry_by_index(index);
721 if (IS_ERR(entry))
722 return PTR_ERR(entry);
670 723
671 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); 724 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key);
672} 725}
673 726
674/* Displays degree Celsius * 1000 */ 727/* Displays degree Celsius * 1000 */
675static ssize_t applesmc_show_temperature(struct device *dev, 728static ssize_t applesmc_show_temperature(struct device *dev,
676 struct device_attribute *devattr, char *sysfsbuf) 729 struct device_attribute *devattr, char *sysfsbuf)
677{ 730{
731 int index = smcreg.temp_begin + to_index(devattr);
732 const struct applesmc_entry *entry;
678 int ret; 733 int ret;
679 u8 buffer[2]; 734 u8 buffer[2];
680 unsigned int temp; 735 unsigned int temp;
681 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
682 const char* key =
683 temperature_sensors_sets[applesmc_temperature_set][attr->index];
684
685 mutex_lock(&applesmc_lock);
686 736
687 ret = applesmc_read_key(key, buffer, 2); 737 entry = applesmc_get_entry_by_index(index);
688 temp = buffer[0]*1000; 738 if (IS_ERR(entry))
689 temp += (buffer[1] >> 6) * 250; 739 return PTR_ERR(entry);
690 740 if (entry->len > 2)
691 mutex_unlock(&applesmc_lock); 741 return -EINVAL;
692 742
743 ret = applesmc_read_entry(entry, buffer, entry->len);
693 if (ret) 744 if (ret)
694 return ret; 745 return ret;
695 else 746
696 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp); 747 if (entry->len == 2) {
748 temp = buffer[0] * 1000;
749 temp += (buffer[1] >> 6) * 250;
750 } else {
751 temp = buffer[0] * 4000;
752 }
753
754 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
697} 755}
698 756
699static ssize_t applesmc_show_fan_speed(struct device *dev, 757static ssize_t applesmc_show_fan_speed(struct device *dev,
@@ -703,21 +761,12 @@ static ssize_t applesmc_show_fan_speed(struct device *dev,
703 unsigned int speed = 0; 761 unsigned int speed = 0;
704 char newkey[5]; 762 char newkey[5];
705 u8 buffer[2]; 763 u8 buffer[2];
706 struct sensor_device_attribute_2 *sensor_attr =
707 to_sensor_dev_attr_2(attr);
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 764
715 mutex_lock(&applesmc_lock); 765 sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr));
716 766
717 ret = applesmc_read_key(newkey, buffer, 2); 767 ret = applesmc_read_key(newkey, buffer, 2);
718 speed = ((buffer[0] << 8 | buffer[1]) >> 2); 768 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
719 769
720 mutex_unlock(&applesmc_lock);
721 if (ret) 770 if (ret)
722 return ret; 771 return ret;
723 else 772 else
@@ -729,30 +778,19 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
729 const char *sysfsbuf, size_t count) 778 const char *sysfsbuf, size_t count)
730{ 779{
731 int ret; 780 int ret;
732 u32 speed; 781 unsigned long speed;
733 char newkey[5]; 782 char newkey[5];
734 u8 buffer[2]; 783 u8 buffer[2];
735 struct sensor_device_attribute_2 *sensor_attr =
736 to_sensor_dev_attr_2(attr);
737
738 speed = simple_strtoul(sysfsbuf, NULL, 10);
739
740 if (speed > 0x4000) /* Bigger than a 14-bit value */
741 return -EINVAL;
742 784
743 newkey[0] = fan_speed_keys[sensor_attr->nr][0]; 785 if (strict_strtoul(sysfsbuf, 10, &speed) < 0 || speed >= 0x4000)
744 newkey[1] = '0' + sensor_attr->index; 786 return -EINVAL; /* Bigger than a 14-bit value */
745 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
746 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
747 newkey[4] = 0;
748 787
749 mutex_lock(&applesmc_lock); 788 sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr));
750 789
751 buffer[0] = (speed >> 6) & 0xff; 790 buffer[0] = (speed >> 6) & 0xff;
752 buffer[1] = (speed << 2) & 0xff; 791 buffer[1] = (speed << 2) & 0xff;
753 ret = applesmc_write_key(newkey, buffer, 2); 792 ret = applesmc_write_key(newkey, buffer, 2);
754 793
755 mutex_unlock(&applesmc_lock);
756 if (ret) 794 if (ret)
757 return ret; 795 return ret;
758 else 796 else
@@ -760,19 +798,15 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
760} 798}
761 799
762static ssize_t applesmc_show_fan_manual(struct device *dev, 800static ssize_t applesmc_show_fan_manual(struct device *dev,
763 struct device_attribute *devattr, char *sysfsbuf) 801 struct device_attribute *attr, char *sysfsbuf)
764{ 802{
765 int ret; 803 int ret;
766 u16 manual = 0; 804 u16 manual = 0;
767 u8 buffer[2]; 805 u8 buffer[2];
768 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
769
770 mutex_lock(&applesmc_lock);
771 806
772 ret = applesmc_read_key(FANS_MANUAL, buffer, 2); 807 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
773 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01; 808 manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01;
774 809
775 mutex_unlock(&applesmc_lock);
776 if (ret) 810 if (ret)
777 return ret; 811 return ret;
778 else 812 else
@@ -780,18 +814,16 @@ static ssize_t applesmc_show_fan_manual(struct device *dev,
780} 814}
781 815
782static ssize_t applesmc_store_fan_manual(struct device *dev, 816static ssize_t applesmc_store_fan_manual(struct device *dev,
783 struct device_attribute *devattr, 817 struct device_attribute *attr,
784 const char *sysfsbuf, size_t count) 818 const char *sysfsbuf, size_t count)
785{ 819{
786 int ret; 820 int ret;
787 u8 buffer[2]; 821 u8 buffer[2];
788 u32 input; 822 unsigned long input;
789 u16 val; 823 u16 val;
790 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
791
792 input = simple_strtoul(sysfsbuf, NULL, 10);
793 824
794 mutex_lock(&applesmc_lock); 825 if (strict_strtoul(sysfsbuf, 10, &input) < 0)
826 return -EINVAL;
795 827
796 ret = applesmc_read_key(FANS_MANUAL, buffer, 2); 828 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
797 val = (buffer[0] << 8 | buffer[1]); 829 val = (buffer[0] << 8 | buffer[1]);
@@ -799,9 +831,9 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
799 goto out; 831 goto out;
800 832
801 if (input) 833 if (input)
802 val = val | (0x01 << attr->index); 834 val = val | (0x01 << to_index(attr));
803 else 835 else
804 val = val & ~(0x01 << attr->index); 836 val = val & ~(0x01 << to_index(attr));
805 837
806 buffer[0] = (val >> 8) & 0xFF; 838 buffer[0] = (val >> 8) & 0xFF;
807 buffer[1] = val & 0xFF; 839 buffer[1] = val & 0xFF;
@@ -809,7 +841,6 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
809 ret = applesmc_write_key(FANS_MANUAL, buffer, 2); 841 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
810 842
811out: 843out:
812 mutex_unlock(&applesmc_lock);
813 if (ret) 844 if (ret)
814 return ret; 845 return ret;
815 else 846 else
@@ -822,21 +853,12 @@ static ssize_t applesmc_show_fan_position(struct device *dev,
822 int ret; 853 int ret;
823 char newkey[5]; 854 char newkey[5];
824 u8 buffer[17]; 855 u8 buffer[17];
825 struct sensor_device_attribute_2 *sensor_attr =
826 to_sensor_dev_attr_2(attr);
827
828 newkey[0] = FAN_POSITION[0];
829 newkey[1] = '0' + sensor_attr->index;
830 newkey[2] = FAN_POSITION[2];
831 newkey[3] = FAN_POSITION[3];
832 newkey[4] = 0;
833 856
834 mutex_lock(&applesmc_lock); 857 sprintf(newkey, FAN_ID_FMT, to_index(attr));
835 858
836 ret = applesmc_read_key(newkey, buffer, 16); 859 ret = applesmc_read_key(newkey, buffer, 16);
837 buffer[16] = 0; 860 buffer[16] = 0;
838 861
839 mutex_unlock(&applesmc_lock);
840 if (ret) 862 if (ret)
841 return ret; 863 return ret;
842 else 864 else
@@ -852,18 +874,14 @@ static ssize_t applesmc_calibrate_show(struct device *dev,
852static ssize_t applesmc_calibrate_store(struct device *dev, 874static ssize_t applesmc_calibrate_store(struct device *dev,
853 struct device_attribute *attr, const char *sysfsbuf, size_t count) 875 struct device_attribute *attr, const char *sysfsbuf, size_t count)
854{ 876{
855 mutex_lock(&applesmc_lock);
856 applesmc_calibrate(); 877 applesmc_calibrate();
857 mutex_unlock(&applesmc_lock);
858 878
859 return count; 879 return count;
860} 880}
861 881
862static void applesmc_backlight_set(struct work_struct *work) 882static void applesmc_backlight_set(struct work_struct *work)
863{ 883{
864 mutex_lock(&applesmc_lock);
865 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2); 884 applesmc_write_key(BACKLIGHT_KEY, backlight_state, 2);
866 mutex_unlock(&applesmc_lock);
867} 885}
868static DECLARE_WORK(backlight_work, &applesmc_backlight_set); 886static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
869 887
@@ -886,13 +904,10 @@ static ssize_t applesmc_key_count_show(struct device *dev,
886 u8 buffer[4]; 904 u8 buffer[4];
887 u32 count; 905 u32 count;
888 906
889 mutex_lock(&applesmc_lock);
890
891 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4); 907 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
892 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) + 908 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
893 ((u32)buffer[2]<<8) + buffer[3]; 909 ((u32)buffer[2]<<8) + buffer[3];
894 910
895 mutex_unlock(&applesmc_lock);
896 if (ret) 911 if (ret)
897 return ret; 912 return ret;
898 else 913 else
@@ -902,113 +917,53 @@ static ssize_t applesmc_key_count_show(struct device *dev,
902static ssize_t applesmc_key_at_index_read_show(struct device *dev, 917static ssize_t applesmc_key_at_index_read_show(struct device *dev,
903 struct device_attribute *attr, char *sysfsbuf) 918 struct device_attribute *attr, char *sysfsbuf)
904{ 919{
905 char key[5]; 920 const struct applesmc_entry *entry;
906 char info[6];
907 int ret; 921 int ret;
908 922
909 mutex_lock(&applesmc_lock); 923 entry = applesmc_get_entry_by_index(key_at_index);
910 924 if (IS_ERR(entry))
911 ret = applesmc_get_key_at_index(key_at_index, key); 925 return PTR_ERR(entry);
912 926 ret = applesmc_read_entry(entry, sysfsbuf, entry->len);
913 if (ret || !key[0]) { 927 if (ret)
914 mutex_unlock(&applesmc_lock);
915
916 return -EINVAL;
917 }
918
919 ret = applesmc_get_key_type(key, info);
920
921 if (ret) {
922 mutex_unlock(&applesmc_lock);
923
924 return ret; 928 return ret;
925 }
926
927 /*
928 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
929 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
930 */
931 ret = applesmc_read_key(key, sysfsbuf, info[0]);
932
933 mutex_unlock(&applesmc_lock);
934 929
935 if (!ret) { 930 return entry->len;
936 return info[0];
937 } else {
938 return ret;
939 }
940} 931}
941 932
942static ssize_t applesmc_key_at_index_data_length_show(struct device *dev, 933static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
943 struct device_attribute *attr, char *sysfsbuf) 934 struct device_attribute *attr, char *sysfsbuf)
944{ 935{
945 char key[5]; 936 const struct applesmc_entry *entry;
946 char info[6];
947 int ret;
948
949 mutex_lock(&applesmc_lock);
950
951 ret = applesmc_get_key_at_index(key_at_index, key);
952 937
953 if (ret || !key[0]) { 938 entry = applesmc_get_entry_by_index(key_at_index);
954 mutex_unlock(&applesmc_lock); 939 if (IS_ERR(entry))
940 return PTR_ERR(entry);
955 941
956 return -EINVAL; 942 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", entry->len);
957 }
958
959 ret = applesmc_get_key_type(key, info);
960
961 mutex_unlock(&applesmc_lock);
962
963 if (!ret)
964 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
965 else
966 return ret;
967} 943}
968 944
969static ssize_t applesmc_key_at_index_type_show(struct device *dev, 945static ssize_t applesmc_key_at_index_type_show(struct device *dev,
970 struct device_attribute *attr, char *sysfsbuf) 946 struct device_attribute *attr, char *sysfsbuf)
971{ 947{
972 char key[5]; 948 const struct applesmc_entry *entry;
973 char info[6];
974 int ret;
975
976 mutex_lock(&applesmc_lock);
977
978 ret = applesmc_get_key_at_index(key_at_index, key);
979
980 if (ret || !key[0]) {
981 mutex_unlock(&applesmc_lock);
982
983 return -EINVAL;
984 }
985
986 ret = applesmc_get_key_type(key, info);
987 949
988 mutex_unlock(&applesmc_lock); 950 entry = applesmc_get_entry_by_index(key_at_index);
951 if (IS_ERR(entry))
952 return PTR_ERR(entry);
989 953
990 if (!ret) 954 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->type);
991 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
992 else
993 return ret;
994} 955}
995 956
996static ssize_t applesmc_key_at_index_name_show(struct device *dev, 957static ssize_t applesmc_key_at_index_name_show(struct device *dev,
997 struct device_attribute *attr, char *sysfsbuf) 958 struct device_attribute *attr, char *sysfsbuf)
998{ 959{
999 char key[5]; 960 const struct applesmc_entry *entry;
1000 int ret;
1001 961
1002 mutex_lock(&applesmc_lock); 962 entry = applesmc_get_entry_by_index(key_at_index);
963 if (IS_ERR(entry))
964 return PTR_ERR(entry);
1003 965
1004 ret = applesmc_get_key_at_index(key_at_index, key); 966 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key);
1005
1006 mutex_unlock(&applesmc_lock);
1007
1008 if (!ret && key[0])
1009 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
1010 else
1011 return -EINVAL;
1012} 967}
1013 968
1014static ssize_t applesmc_key_at_index_show(struct device *dev, 969static ssize_t applesmc_key_at_index_show(struct device *dev,
@@ -1020,12 +975,13 @@ static ssize_t applesmc_key_at_index_show(struct device *dev,
1020static ssize_t applesmc_key_at_index_store(struct device *dev, 975static ssize_t applesmc_key_at_index_store(struct device *dev,
1021 struct device_attribute *attr, const char *sysfsbuf, size_t count) 976 struct device_attribute *attr, const char *sysfsbuf, size_t count)
1022{ 977{
1023 mutex_lock(&applesmc_lock); 978 unsigned long newkey;
1024
1025 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
1026 979
1027 mutex_unlock(&applesmc_lock); 980 if (strict_strtoul(sysfsbuf, 10, &newkey) < 0
981 || newkey >= smcreg.key_count)
982 return -EINVAL;
1028 983
984 key_at_index = newkey;
1029 return count; 985 return count;
1030} 986}
1031 987
@@ -1035,387 +991,102 @@ static struct led_classdev applesmc_backlight = {
1035 .brightness_set = applesmc_brightness_set, 991 .brightness_set = applesmc_brightness_set,
1036}; 992};
1037 993
1038static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL); 994static struct applesmc_node_group info_group[] = {
1039 995 { "name", applesmc_name_show },
1040static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL); 996 { "key_count", applesmc_key_count_show },
1041static DEVICE_ATTR(calibrate, 0644, 997 { "key_at_index", applesmc_key_at_index_show, applesmc_key_at_index_store },
1042 applesmc_calibrate_show, applesmc_calibrate_store); 998 { "key_at_index_name", applesmc_key_at_index_name_show },
1043 999 { "key_at_index_type", applesmc_key_at_index_type_show },
1044static struct attribute *accelerometer_attributes[] = { 1000 { "key_at_index_data_length", applesmc_key_at_index_data_length_show },
1045 &dev_attr_position.attr, 1001 { "key_at_index_data", applesmc_key_at_index_read_show },
1046 &dev_attr_calibrate.attr, 1002 { }
1047 NULL
1048};
1049
1050static const struct attribute_group accelerometer_attributes_group =
1051 { .attrs = accelerometer_attributes };
1052
1053static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
1054
1055static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
1056static DEVICE_ATTR(key_at_index, 0644,
1057 applesmc_key_at_index_show, applesmc_key_at_index_store);
1058static DEVICE_ATTR(key_at_index_name, 0444,
1059 applesmc_key_at_index_name_show, NULL);
1060static DEVICE_ATTR(key_at_index_type, 0444,
1061 applesmc_key_at_index_type_show, NULL);
1062static DEVICE_ATTR(key_at_index_data_length, 0444,
1063 applesmc_key_at_index_data_length_show, NULL);
1064static DEVICE_ATTR(key_at_index_data, 0444,
1065 applesmc_key_at_index_read_show, NULL);
1066
1067static struct attribute *key_enumeration_attributes[] = {
1068 &dev_attr_key_count.attr,
1069 &dev_attr_key_at_index.attr,
1070 &dev_attr_key_at_index_name.attr,
1071 &dev_attr_key_at_index_type.attr,
1072 &dev_attr_key_at_index_data_length.attr,
1073 &dev_attr_key_at_index_data.attr,
1074 NULL
1075};
1076
1077static const struct attribute_group key_enumeration_group =
1078 { .attrs = key_enumeration_attributes };
1079
1080/*
1081 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
1082 * - show actual speed
1083 * - show/store minimum speed
1084 * - show maximum speed
1085 * - show safe speed
1086 * - show/store target speed
1087 * - show/store manual mode
1088 */
1089#define sysfs_fan_speeds_offset(offset) \
1090static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
1091 applesmc_show_fan_speed, NULL, 0, offset-1); \
1092\
1093static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
1094 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
1095\
1096static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
1097 applesmc_show_fan_speed, NULL, 2, offset-1); \
1098\
1099static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
1100 applesmc_show_fan_speed, NULL, 3, offset-1); \
1101\
1102static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
1103 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
1104\
1105static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
1106 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
1107\
1108static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \
1109 applesmc_show_fan_position, NULL, offset-1); \
1110\
1111static struct attribute *fan##offset##_attributes[] = { \
1112 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
1113 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
1114 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
1115 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
1116 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
1117 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
1118 &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \
1119 NULL \
1120}; 1003};
1121 1004
1122/* 1005static struct applesmc_node_group accelerometer_group[] = {
1123 * Create the needed functions for each fan using the macro defined above 1006 { "position", applesmc_position_show },
1124 * (4 fans are supported) 1007 { "calibrate", applesmc_calibrate_show, applesmc_calibrate_store },
1125 */ 1008 { }
1126sysfs_fan_speeds_offset(1);
1127sysfs_fan_speeds_offset(2);
1128sysfs_fan_speeds_offset(3);
1129sysfs_fan_speeds_offset(4);
1130
1131static const struct attribute_group fan_attribute_groups[] = {
1132 { .attrs = fan1_attributes },
1133 { .attrs = fan2_attributes },
1134 { .attrs = fan3_attributes },
1135 { .attrs = fan4_attributes },
1136}; 1009};
1137 1010
1138/* 1011static struct applesmc_node_group light_sensor_group[] = {
1139 * Temperature sensors sysfs entries. 1012 { "light", applesmc_light_show },
1140 */ 1013 { }
1141static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO,
1142 applesmc_show_sensor_label, NULL, 0);
1143static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO,
1144 applesmc_show_sensor_label, NULL, 1);
1145static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO,
1146 applesmc_show_sensor_label, NULL, 2);
1147static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO,
1148 applesmc_show_sensor_label, NULL, 3);
1149static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO,
1150 applesmc_show_sensor_label, NULL, 4);
1151static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO,
1152 applesmc_show_sensor_label, NULL, 5);
1153static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO,
1154 applesmc_show_sensor_label, NULL, 6);
1155static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO,
1156 applesmc_show_sensor_label, NULL, 7);
1157static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO,
1158 applesmc_show_sensor_label, NULL, 8);
1159static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO,
1160 applesmc_show_sensor_label, NULL, 9);
1161static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO,
1162 applesmc_show_sensor_label, NULL, 10);
1163static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO,
1164 applesmc_show_sensor_label, NULL, 11);
1165static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO,
1166 applesmc_show_sensor_label, NULL, 12);
1167static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO,
1168 applesmc_show_sensor_label, NULL, 13);
1169static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO,
1170 applesmc_show_sensor_label, NULL, 14);
1171static SENSOR_DEVICE_ATTR(temp16_label, S_IRUGO,
1172 applesmc_show_sensor_label, NULL, 15);
1173static SENSOR_DEVICE_ATTR(temp17_label, S_IRUGO,
1174 applesmc_show_sensor_label, NULL, 16);
1175static SENSOR_DEVICE_ATTR(temp18_label, S_IRUGO,
1176 applesmc_show_sensor_label, NULL, 17);
1177static SENSOR_DEVICE_ATTR(temp19_label, S_IRUGO,
1178 applesmc_show_sensor_label, NULL, 18);
1179static SENSOR_DEVICE_ATTR(temp20_label, S_IRUGO,
1180 applesmc_show_sensor_label, NULL, 19);
1181static SENSOR_DEVICE_ATTR(temp21_label, S_IRUGO,
1182 applesmc_show_sensor_label, NULL, 20);
1183static SENSOR_DEVICE_ATTR(temp22_label, S_IRUGO,
1184 applesmc_show_sensor_label, NULL, 21);
1185static SENSOR_DEVICE_ATTR(temp23_label, S_IRUGO,
1186 applesmc_show_sensor_label, NULL, 22);
1187static SENSOR_DEVICE_ATTR(temp24_label, S_IRUGO,
1188 applesmc_show_sensor_label, NULL, 23);
1189static SENSOR_DEVICE_ATTR(temp25_label, S_IRUGO,
1190 applesmc_show_sensor_label, NULL, 24);
1191static SENSOR_DEVICE_ATTR(temp26_label, S_IRUGO,
1192 applesmc_show_sensor_label, NULL, 25);
1193static SENSOR_DEVICE_ATTR(temp27_label, S_IRUGO,
1194 applesmc_show_sensor_label, NULL, 26);
1195static SENSOR_DEVICE_ATTR(temp28_label, S_IRUGO,
1196 applesmc_show_sensor_label, NULL, 27);
1197static SENSOR_DEVICE_ATTR(temp29_label, S_IRUGO,
1198 applesmc_show_sensor_label, NULL, 28);
1199static SENSOR_DEVICE_ATTR(temp30_label, S_IRUGO,
1200 applesmc_show_sensor_label, NULL, 29);
1201static SENSOR_DEVICE_ATTR(temp31_label, S_IRUGO,
1202 applesmc_show_sensor_label, NULL, 30);
1203static SENSOR_DEVICE_ATTR(temp32_label, S_IRUGO,
1204 applesmc_show_sensor_label, NULL, 31);
1205static SENSOR_DEVICE_ATTR(temp33_label, S_IRUGO,
1206 applesmc_show_sensor_label, NULL, 32);
1207static SENSOR_DEVICE_ATTR(temp34_label, S_IRUGO,
1208 applesmc_show_sensor_label, NULL, 33);
1209static SENSOR_DEVICE_ATTR(temp35_label, S_IRUGO,
1210 applesmc_show_sensor_label, NULL, 34);
1211static SENSOR_DEVICE_ATTR(temp36_label, S_IRUGO,
1212 applesmc_show_sensor_label, NULL, 35);
1213static SENSOR_DEVICE_ATTR(temp37_label, S_IRUGO,
1214 applesmc_show_sensor_label, NULL, 36);
1215static SENSOR_DEVICE_ATTR(temp38_label, S_IRUGO,
1216 applesmc_show_sensor_label, NULL, 37);
1217static SENSOR_DEVICE_ATTR(temp39_label, S_IRUGO,
1218 applesmc_show_sensor_label, NULL, 38);
1219static SENSOR_DEVICE_ATTR(temp40_label, S_IRUGO,
1220 applesmc_show_sensor_label, NULL, 39);
1221static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1222 applesmc_show_temperature, NULL, 0);
1223static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1224 applesmc_show_temperature, NULL, 1);
1225static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1226 applesmc_show_temperature, NULL, 2);
1227static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1228 applesmc_show_temperature, NULL, 3);
1229static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1230 applesmc_show_temperature, NULL, 4);
1231static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1232 applesmc_show_temperature, NULL, 5);
1233static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1234 applesmc_show_temperature, NULL, 6);
1235static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1236 applesmc_show_temperature, NULL, 7);
1237static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1238 applesmc_show_temperature, NULL, 8);
1239static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1240 applesmc_show_temperature, NULL, 9);
1241static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1242 applesmc_show_temperature, NULL, 10);
1243static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1244 applesmc_show_temperature, NULL, 11);
1245static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1246 applesmc_show_temperature, NULL, 12);
1247static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1248 applesmc_show_temperature, NULL, 13);
1249static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1250 applesmc_show_temperature, NULL, 14);
1251static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1252 applesmc_show_temperature, NULL, 15);
1253static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1254 applesmc_show_temperature, NULL, 16);
1255static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1256 applesmc_show_temperature, NULL, 17);
1257static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1258 applesmc_show_temperature, NULL, 18);
1259static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1260 applesmc_show_temperature, NULL, 19);
1261static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1262 applesmc_show_temperature, NULL, 20);
1263static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1264 applesmc_show_temperature, NULL, 21);
1265static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1266 applesmc_show_temperature, NULL, 22);
1267static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1268 applesmc_show_temperature, NULL, 23);
1269static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1270 applesmc_show_temperature, NULL, 24);
1271static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1272 applesmc_show_temperature, NULL, 25);
1273static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1274 applesmc_show_temperature, NULL, 26);
1275static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1276 applesmc_show_temperature, NULL, 27);
1277static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1278 applesmc_show_temperature, NULL, 28);
1279static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1280 applesmc_show_temperature, NULL, 29);
1281static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1282 applesmc_show_temperature, NULL, 30);
1283static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1284 applesmc_show_temperature, NULL, 31);
1285static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1286 applesmc_show_temperature, NULL, 32);
1287static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1288 applesmc_show_temperature, NULL, 33);
1289static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1290 applesmc_show_temperature, NULL, 34);
1291static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
1292 applesmc_show_temperature, NULL, 35);
1293static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
1294 applesmc_show_temperature, NULL, 36);
1295static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
1296 applesmc_show_temperature, NULL, 37);
1297static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
1298 applesmc_show_temperature, NULL, 38);
1299static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
1300 applesmc_show_temperature, NULL, 39);
1301
1302static struct attribute *label_attributes[] = {
1303 &sensor_dev_attr_temp1_label.dev_attr.attr,
1304 &sensor_dev_attr_temp2_label.dev_attr.attr,
1305 &sensor_dev_attr_temp3_label.dev_attr.attr,
1306 &sensor_dev_attr_temp4_label.dev_attr.attr,
1307 &sensor_dev_attr_temp5_label.dev_attr.attr,
1308 &sensor_dev_attr_temp6_label.dev_attr.attr,
1309 &sensor_dev_attr_temp7_label.dev_attr.attr,
1310 &sensor_dev_attr_temp8_label.dev_attr.attr,
1311 &sensor_dev_attr_temp9_label.dev_attr.attr,
1312 &sensor_dev_attr_temp10_label.dev_attr.attr,
1313 &sensor_dev_attr_temp11_label.dev_attr.attr,
1314 &sensor_dev_attr_temp12_label.dev_attr.attr,
1315 &sensor_dev_attr_temp13_label.dev_attr.attr,
1316 &sensor_dev_attr_temp14_label.dev_attr.attr,
1317 &sensor_dev_attr_temp15_label.dev_attr.attr,
1318 &sensor_dev_attr_temp16_label.dev_attr.attr,
1319 &sensor_dev_attr_temp17_label.dev_attr.attr,
1320 &sensor_dev_attr_temp18_label.dev_attr.attr,
1321 &sensor_dev_attr_temp19_label.dev_attr.attr,
1322 &sensor_dev_attr_temp20_label.dev_attr.attr,
1323 &sensor_dev_attr_temp21_label.dev_attr.attr,
1324 &sensor_dev_attr_temp22_label.dev_attr.attr,
1325 &sensor_dev_attr_temp23_label.dev_attr.attr,
1326 &sensor_dev_attr_temp24_label.dev_attr.attr,
1327 &sensor_dev_attr_temp25_label.dev_attr.attr,
1328 &sensor_dev_attr_temp26_label.dev_attr.attr,
1329 &sensor_dev_attr_temp27_label.dev_attr.attr,
1330 &sensor_dev_attr_temp28_label.dev_attr.attr,
1331 &sensor_dev_attr_temp29_label.dev_attr.attr,
1332 &sensor_dev_attr_temp30_label.dev_attr.attr,
1333 &sensor_dev_attr_temp31_label.dev_attr.attr,
1334 &sensor_dev_attr_temp32_label.dev_attr.attr,
1335 &sensor_dev_attr_temp33_label.dev_attr.attr,
1336 &sensor_dev_attr_temp34_label.dev_attr.attr,
1337 &sensor_dev_attr_temp35_label.dev_attr.attr,
1338 &sensor_dev_attr_temp36_label.dev_attr.attr,
1339 &sensor_dev_attr_temp37_label.dev_attr.attr,
1340 &sensor_dev_attr_temp38_label.dev_attr.attr,
1341 &sensor_dev_attr_temp39_label.dev_attr.attr,
1342 &sensor_dev_attr_temp40_label.dev_attr.attr,
1343 NULL
1344}; 1014};
1345 1015
1346static struct attribute *temperature_attributes[] = { 1016static struct applesmc_node_group fan_group[] = {
1347 &sensor_dev_attr_temp1_input.dev_attr.attr, 1017 { "fan%d_label", applesmc_show_fan_position },
1348 &sensor_dev_attr_temp2_input.dev_attr.attr, 1018 { "fan%d_input", applesmc_show_fan_speed, NULL, 0 },
1349 &sensor_dev_attr_temp3_input.dev_attr.attr, 1019 { "fan%d_min", applesmc_show_fan_speed, applesmc_store_fan_speed, 1 },
1350 &sensor_dev_attr_temp4_input.dev_attr.attr, 1020 { "fan%d_max", applesmc_show_fan_speed, NULL, 2 },
1351 &sensor_dev_attr_temp5_input.dev_attr.attr, 1021 { "fan%d_safe", applesmc_show_fan_speed, NULL, 3 },
1352 &sensor_dev_attr_temp6_input.dev_attr.attr, 1022 { "fan%d_output", applesmc_show_fan_speed, applesmc_store_fan_speed, 4 },
1353 &sensor_dev_attr_temp7_input.dev_attr.attr, 1023 { "fan%d_manual", applesmc_show_fan_manual, applesmc_store_fan_manual },
1354 &sensor_dev_attr_temp8_input.dev_attr.attr, 1024 { }
1355 &sensor_dev_attr_temp9_input.dev_attr.attr,
1356 &sensor_dev_attr_temp10_input.dev_attr.attr,
1357 &sensor_dev_attr_temp11_input.dev_attr.attr,
1358 &sensor_dev_attr_temp12_input.dev_attr.attr,
1359 &sensor_dev_attr_temp13_input.dev_attr.attr,
1360 &sensor_dev_attr_temp14_input.dev_attr.attr,
1361 &sensor_dev_attr_temp15_input.dev_attr.attr,
1362 &sensor_dev_attr_temp16_input.dev_attr.attr,
1363 &sensor_dev_attr_temp17_input.dev_attr.attr,
1364 &sensor_dev_attr_temp18_input.dev_attr.attr,
1365 &sensor_dev_attr_temp19_input.dev_attr.attr,
1366 &sensor_dev_attr_temp20_input.dev_attr.attr,
1367 &sensor_dev_attr_temp21_input.dev_attr.attr,
1368 &sensor_dev_attr_temp22_input.dev_attr.attr,
1369 &sensor_dev_attr_temp23_input.dev_attr.attr,
1370 &sensor_dev_attr_temp24_input.dev_attr.attr,
1371 &sensor_dev_attr_temp25_input.dev_attr.attr,
1372 &sensor_dev_attr_temp26_input.dev_attr.attr,
1373 &sensor_dev_attr_temp27_input.dev_attr.attr,
1374 &sensor_dev_attr_temp28_input.dev_attr.attr,
1375 &sensor_dev_attr_temp29_input.dev_attr.attr,
1376 &sensor_dev_attr_temp30_input.dev_attr.attr,
1377 &sensor_dev_attr_temp31_input.dev_attr.attr,
1378 &sensor_dev_attr_temp32_input.dev_attr.attr,
1379 &sensor_dev_attr_temp33_input.dev_attr.attr,
1380 &sensor_dev_attr_temp34_input.dev_attr.attr,
1381 &sensor_dev_attr_temp35_input.dev_attr.attr,
1382 &sensor_dev_attr_temp36_input.dev_attr.attr,
1383 &sensor_dev_attr_temp37_input.dev_attr.attr,
1384 &sensor_dev_attr_temp38_input.dev_attr.attr,
1385 &sensor_dev_attr_temp39_input.dev_attr.attr,
1386 &sensor_dev_attr_temp40_input.dev_attr.attr,
1387 NULL
1388}; 1025};
1389 1026
1390static const struct attribute_group temperature_attributes_group = 1027static struct applesmc_node_group temp_group[] = {
1391 { .attrs = temperature_attributes }; 1028 { "temp%d_label", applesmc_show_sensor_label },
1392 1029 { "temp%d_input", applesmc_show_temperature },
1393static const struct attribute_group label_attributes_group = { 1030 { }
1394 .attrs = label_attributes
1395}; 1031};
1396 1032
1397/* Module stuff */ 1033/* Module stuff */
1398 1034
1399/* 1035/*
1400 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt. 1036 * applesmc_destroy_nodes - remove files and free associated memory
1401 */ 1037 */
1402static int applesmc_dmi_match(const struct dmi_system_id *id) 1038static void applesmc_destroy_nodes(struct applesmc_node_group *groups)
1403{ 1039{
1404 int i = 0; 1040 struct applesmc_node_group *grp;
1405 struct dmi_match_data* dmi_data = id->driver_data; 1041 struct applesmc_dev_attr *node;
1406 printk(KERN_INFO "applesmc: %s detected:\n", id->ident); 1042
1407 applesmc_accelerometer = dmi_data->accelerometer; 1043 for (grp = groups; grp->nodes; grp++) {
1408 printk(KERN_INFO "applesmc: - Model %s accelerometer\n", 1044 for (node = grp->nodes; node->sda.dev_attr.attr.name; node++)
1409 applesmc_accelerometer ? "with" : "without"); 1045 sysfs_remove_file(&pdev->dev.kobj,
1410 applesmc_light = dmi_data->light; 1046 &node->sda.dev_attr.attr);
1411 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n", 1047 kfree(grp->nodes);
1412 applesmc_light ? "with" : "without"); 1048 grp->nodes = NULL;
1413 1049 }
1414 applesmc_temperature_set = dmi_data->temperature_set; 1050}
1415 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL) 1051
1416 i++; 1052/*
1417 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i); 1053 * applesmc_create_nodes - create a two-dimensional group of sysfs files
1418 return 1; 1054 */
1055static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
1056{
1057 struct applesmc_node_group *grp;
1058 struct applesmc_dev_attr *node;
1059 struct attribute *attr;
1060 int ret, i;
1061
1062 for (grp = groups; grp->format; grp++) {
1063 grp->nodes = kcalloc(num + 1, sizeof(*node), GFP_KERNEL);
1064 if (!grp->nodes) {
1065 ret = -ENOMEM;
1066 goto out;
1067 }
1068 for (i = 0; i < num; i++) {
1069 node = &grp->nodes[i];
1070 sprintf(node->name, grp->format, i + 1);
1071 node->sda.index = (grp->option << 16) | (i & 0xffff);
1072 node->sda.dev_attr.show = grp->show;
1073 node->sda.dev_attr.store = grp->store;
1074 attr = &node->sda.dev_attr.attr;
1075 sysfs_attr_init(attr);
1076 attr->name = node->name;
1077 attr->mode = S_IRUGO | (grp->store ? S_IWUSR : 0);
1078 ret = sysfs_create_file(&pdev->dev.kobj, attr);
1079 if (ret) {
1080 attr->name = NULL;
1081 goto out;
1082 }
1083 }
1084 }
1085
1086 return 0;
1087out:
1088 applesmc_destroy_nodes(groups);
1089 return ret;
1419} 1090}
1420 1091
1421/* Create accelerometer ressources */ 1092/* Create accelerometer ressources */
@@ -1424,8 +1095,10 @@ static int applesmc_create_accelerometer(void)
1424 struct input_dev *idev; 1095 struct input_dev *idev;
1425 int ret; 1096 int ret;
1426 1097
1427 ret = sysfs_create_group(&pdev->dev.kobj, 1098 if (!smcreg.has_accelerometer)
1428 &accelerometer_attributes_group); 1099 return 0;
1100
1101 ret = applesmc_create_nodes(accelerometer_group, 1);
1429 if (ret) 1102 if (ret)
1430 goto out; 1103 goto out;
1431 1104
@@ -1462,184 +1135,96 @@ out_idev:
1462 input_free_polled_device(applesmc_idev); 1135 input_free_polled_device(applesmc_idev);
1463 1136
1464out_sysfs: 1137out_sysfs:
1465 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); 1138 applesmc_destroy_nodes(accelerometer_group);
1466 1139
1467out: 1140out:
1468 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret); 1141 pr_warn("driver init failed (ret=%d)!\n", ret);
1469 return ret; 1142 return ret;
1470} 1143}
1471 1144
1472/* Release all ressources used by the accelerometer */ 1145/* Release all ressources used by the accelerometer */
1473static void applesmc_release_accelerometer(void) 1146static void applesmc_release_accelerometer(void)
1474{ 1147{
1148 if (!smcreg.has_accelerometer)
1149 return;
1475 input_unregister_polled_device(applesmc_idev); 1150 input_unregister_polled_device(applesmc_idev);
1476 input_free_polled_device(applesmc_idev); 1151 input_free_polled_device(applesmc_idev);
1477 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); 1152 applesmc_destroy_nodes(accelerometer_group);
1478} 1153}
1479 1154
1480static __initdata struct dmi_match_data applesmc_dmi_data[] = { 1155static int applesmc_create_light_sensor(void)
1481/* MacBook Pro: accelerometer, backlight and temperature set 0 */ 1156{
1482 { .accelerometer = 1, .light = 1, .temperature_set = 0 }, 1157 if (!smcreg.num_light_sensors)
1483/* MacBook2: accelerometer and temperature set 1 */ 1158 return 0;
1484 { .accelerometer = 1, .light = 0, .temperature_set = 1 }, 1159 return applesmc_create_nodes(light_sensor_group, 1);
1485/* MacBook: accelerometer and temperature set 2 */ 1160}
1486 { .accelerometer = 1, .light = 0, .temperature_set = 2 }, 1161
1487/* MacMini: temperature set 3 */ 1162static void applesmc_release_light_sensor(void)
1488 { .accelerometer = 0, .light = 0, .temperature_set = 3 }, 1163{
1489/* MacPro: temperature set 4 */ 1164 if (!smcreg.num_light_sensors)
1490 { .accelerometer = 0, .light = 0, .temperature_set = 4 }, 1165 return;
1491/* iMac: temperature set 5 */ 1166 applesmc_destroy_nodes(light_sensor_group);
1492 { .accelerometer = 0, .light = 0, .temperature_set = 5 }, 1167}
1493/* MacBook3, MacBook4: accelerometer and temperature set 6 */ 1168
1494 { .accelerometer = 1, .light = 0, .temperature_set = 6 }, 1169static int applesmc_create_key_backlight(void)
1495/* MacBook Air: accelerometer, backlight and temperature set 7 */ 1170{
1496 { .accelerometer = 1, .light = 1, .temperature_set = 7 }, 1171 if (!smcreg.has_key_backlight)
1497/* MacBook Pro 4: accelerometer, backlight and temperature set 8 */ 1172 return 0;
1498 { .accelerometer = 1, .light = 1, .temperature_set = 8 }, 1173 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1499/* MacBook Pro 3: accelerometer, backlight and temperature set 9 */ 1174 if (!applesmc_led_wq)
1500 { .accelerometer = 1, .light = 1, .temperature_set = 9 }, 1175 return -ENOMEM;
1501/* iMac 5: light sensor only, temperature set 10 */ 1176 return led_classdev_register(&pdev->dev, &applesmc_backlight);
1502 { .accelerometer = 0, .light = 0, .temperature_set = 10 }, 1177}
1503/* MacBook 5: accelerometer, backlight and temperature set 11 */ 1178
1504 { .accelerometer = 1, .light = 1, .temperature_set = 11 }, 1179static void applesmc_release_key_backlight(void)
1505/* MacBook Pro 5: accelerometer, backlight and temperature set 12 */ 1180{
1506 { .accelerometer = 1, .light = 1, .temperature_set = 12 }, 1181 if (!smcreg.has_key_backlight)
1507/* iMac 8: light sensor only, temperature set 13 */ 1182 return;
1508 { .accelerometer = 0, .light = 0, .temperature_set = 13 }, 1183 led_classdev_unregister(&applesmc_backlight);
1509/* iMac 6: light sensor only, temperature set 14 */ 1184 destroy_workqueue(applesmc_led_wq);
1510 { .accelerometer = 0, .light = 0, .temperature_set = 14 }, 1185}
1511/* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */ 1186
1512 { .accelerometer = 1, .light = 1, .temperature_set = 15 }, 1187static int applesmc_dmi_match(const struct dmi_system_id *id)
1513/* MacPro3,1: temperature set 16 */ 1188{
1514 { .accelerometer = 0, .light = 0, .temperature_set = 16 }, 1189 return 1;
1515/* iMac 9,1: light sensor only, temperature set 17 */ 1190}
1516 { .accelerometer = 0, .light = 0, .temperature_set = 17 },
1517/* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
1518 { .accelerometer = 1, .light = 1, .temperature_set = 18 },
1519/* MacBook Pro 5,3: accelerometer, backlight and temperature set 19 */
1520 { .accelerometer = 1, .light = 1, .temperature_set = 19 },
1521/* MacBook Pro 5,4: accelerometer, backlight and temperature set 20 */
1522 { .accelerometer = 1, .light = 1, .temperature_set = 20 },
1523/* MacBook Pro 6,2: accelerometer, backlight and temperature set 21 */
1524 { .accelerometer = 1, .light = 1, .temperature_set = 21 },
1525/* MacBook Pro 7,1: accelerometer, backlight and temperature set 22 */
1526 { .accelerometer = 1, .light = 1, .temperature_set = 22 },
1527};
1528 1191
1529/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". 1192/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1530 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ 1193 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1531static __initdata struct dmi_system_id applesmc_whitelist[] = { 1194static __initdata struct dmi_system_id applesmc_whitelist[] = {
1532 { applesmc_dmi_match, "Apple MacBook Air 2", {
1533 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1534 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
1535 &applesmc_dmi_data[15]},
1536 { applesmc_dmi_match, "Apple MacBook Air", { 1195 { applesmc_dmi_match, "Apple MacBook Air", {
1537 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), 1196 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1538 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, 1197 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
1539 &applesmc_dmi_data[7]}, 1198 },
1540 { applesmc_dmi_match, "Apple MacBook Pro 7", {
1541 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1542 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro7") },
1543 &applesmc_dmi_data[22]},
1544 { applesmc_dmi_match, "Apple MacBook Pro 5,4", {
1545 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1546 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4") },
1547 &applesmc_dmi_data[20]},
1548 { applesmc_dmi_match, "Apple MacBook Pro 5,3", {
1549 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1550 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3") },
1551 &applesmc_dmi_data[19]},
1552 { applesmc_dmi_match, "Apple MacBook Pro 6", {
1553 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1554 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6") },
1555 &applesmc_dmi_data[21]},
1556 { applesmc_dmi_match, "Apple MacBook Pro 5", {
1557 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1558 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") },
1559 &applesmc_dmi_data[12]},
1560 { applesmc_dmi_match, "Apple MacBook Pro 4", {
1561 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1562 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
1563 &applesmc_dmi_data[8]},
1564 { applesmc_dmi_match, "Apple MacBook Pro 3", {
1565 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1566 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
1567 &applesmc_dmi_data[9]},
1568 { applesmc_dmi_match, "Apple MacBook Pro 2,2", {
1569 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
1570 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
1571 &applesmc_dmi_data[18]},
1572 { applesmc_dmi_match, "Apple MacBook Pro", { 1199 { applesmc_dmi_match, "Apple MacBook Pro", {
1573 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1574 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1575 &applesmc_dmi_data[0]},
1576 { applesmc_dmi_match, "Apple MacBook (v2)", {
1577 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1578 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1579 &applesmc_dmi_data[1]},
1580 { applesmc_dmi_match, "Apple MacBook (v3)", {
1581 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1582 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1583 &applesmc_dmi_data[6]},
1584 { applesmc_dmi_match, "Apple MacBook 4", {
1585 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1586 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") },
1587 &applesmc_dmi_data[6]},
1588 { applesmc_dmi_match, "Apple MacBook 5", {
1589 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), 1200 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1590 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") }, 1201 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro") },
1591 &applesmc_dmi_data[11]}, 1202 },
1592 { applesmc_dmi_match, "Apple MacBook", { 1203 { applesmc_dmi_match, "Apple MacBook", {
1593 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1204 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1594 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, 1205 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook") },
1595 &applesmc_dmi_data[2]}, 1206 },
1596 { applesmc_dmi_match, "Apple Macmini", { 1207 { applesmc_dmi_match, "Apple Macmini", {
1597 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1598 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1599 &applesmc_dmi_data[3]},
1600 { applesmc_dmi_match, "Apple MacPro2", {
1601 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1602 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1603 &applesmc_dmi_data[4]},
1604 { applesmc_dmi_match, "Apple MacPro3", {
1605 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), 1208 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1606 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") }, 1209 DMI_MATCH(DMI_PRODUCT_NAME, "Macmini") },
1607 &applesmc_dmi_data[16]}, 1210 },
1608 { applesmc_dmi_match, "Apple MacPro", { 1211 { applesmc_dmi_match, "Apple MacPro", {
1609 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), 1212 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1610 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, 1213 DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
1611 &applesmc_dmi_data[4]}, 1214 },
1612 { applesmc_dmi_match, "Apple iMac 9,1", {
1613 DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
1614 DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
1615 &applesmc_dmi_data[17]},
1616 { applesmc_dmi_match, "Apple iMac 8", {
1617 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1618 DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
1619 &applesmc_dmi_data[13]},
1620 { applesmc_dmi_match, "Apple iMac 6", {
1621 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1622 DMI_MATCH(DMI_PRODUCT_NAME, "iMac6") },
1623 &applesmc_dmi_data[14]},
1624 { applesmc_dmi_match, "Apple iMac 5", {
1625 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1626 DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") },
1627 &applesmc_dmi_data[10]},
1628 { applesmc_dmi_match, "Apple iMac", { 1215 { applesmc_dmi_match, "Apple iMac", {
1629 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1216 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
1630 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, 1217 DMI_MATCH(DMI_PRODUCT_NAME, "iMac") },
1631 &applesmc_dmi_data[5]}, 1218 },
1632 { .ident = NULL } 1219 { .ident = NULL }
1633}; 1220};
1634 1221
1635static int __init applesmc_init(void) 1222static int __init applesmc_init(void)
1636{ 1223{
1637 int ret; 1224 int ret;
1638 int count;
1639 int i;
1640 1225
1641 if (!dmi_check_system(applesmc_whitelist)) { 1226 if (!dmi_check_system(applesmc_whitelist)) {
1642 printk(KERN_WARNING "applesmc: supported laptop not found!\n"); 1227 pr_warn("supported laptop not found!\n");
1643 ret = -ENODEV; 1228 ret = -ENODEV;
1644 goto out; 1229 goto out;
1645 } 1230 }
@@ -1661,83 +1246,34 @@ static int __init applesmc_init(void)
1661 goto out_driver; 1246 goto out_driver;
1662 } 1247 }
1663 1248
1664 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr); 1249 /* create register cache */
1250 ret = applesmc_init_smcreg();
1665 if (ret) 1251 if (ret)
1666 goto out_device; 1252 goto out_device;
1667 1253
1668 /* Create key enumeration sysfs files */ 1254 ret = applesmc_create_nodes(info_group, 1);
1669 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1670 if (ret) 1255 if (ret)
1671 goto out_name; 1256 goto out_smcreg;
1672
1673 /* create fan files */
1674 count = applesmc_get_fan_count();
1675 if (count < 0)
1676 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1677 else
1678 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1679 1257
1680 if (count > 4) { 1258 ret = applesmc_create_nodes(fan_group, smcreg.fan_count);
1681 count = 4; 1259 if (ret)
1682 printk(KERN_WARNING "applesmc: More than 4 fans found," 1260 goto out_info;
1683 " but at most 4 fans are supported"
1684 " by the driver.\n");
1685 }
1686
1687 while (fans_handled < count) {
1688 ret = sysfs_create_group(&pdev->dev.kobj,
1689 &fan_attribute_groups[fans_handled]);
1690 if (ret)
1691 goto out_fans;
1692 fans_handled++;
1693 }
1694
1695 for (i = 0;
1696 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1697 i++) {
1698 if (temperature_attributes[i] == NULL ||
1699 label_attributes[i] == NULL) {
1700 printk(KERN_ERR "applesmc: More temperature sensors "
1701 "in temperature_sensors_sets (at least %i)"
1702 "than available sysfs files in "
1703 "temperature_attributes (%i), please report "
1704 "this bug.\n", i, i-1);
1705 goto out_temperature;
1706 }
1707 ret = sysfs_create_file(&pdev->dev.kobj,
1708 temperature_attributes[i]);
1709 if (ret)
1710 goto out_temperature;
1711 ret = sysfs_create_file(&pdev->dev.kobj,
1712 label_attributes[i]);
1713 if (ret)
1714 goto out_temperature;
1715 }
1716 1261
1717 if (applesmc_accelerometer) { 1262 ret = applesmc_create_nodes(temp_group, smcreg.temp_count);
1718 ret = applesmc_create_accelerometer(); 1263 if (ret)
1719 if (ret) 1264 goto out_fans;
1720 goto out_temperature;
1721 }
1722 1265
1723 if (applesmc_light) { 1266 ret = applesmc_create_accelerometer();
1724 /* Add light sensor file */ 1267 if (ret)
1725 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr); 1268 goto out_temperature;
1726 if (ret)
1727 goto out_accelerometer;
1728 1269
1729 /* Create the workqueue */ 1270 ret = applesmc_create_light_sensor();
1730 applesmc_led_wq = create_singlethread_workqueue("applesmc-led"); 1271 if (ret)
1731 if (!applesmc_led_wq) { 1272 goto out_accelerometer;
1732 ret = -ENOMEM;
1733 goto out_light_sysfs;
1734 }
1735 1273
1736 /* register as a led device */ 1274 ret = applesmc_create_key_backlight();
1737 ret = led_classdev_register(&pdev->dev, &applesmc_backlight); 1275 if (ret)
1738 if (ret < 0) 1276 goto out_light_sysfs;
1739 goto out_light_wq;
1740 }
1741 1277
1742 hwmon_dev = hwmon_device_register(&pdev->dev); 1278 hwmon_dev = hwmon_device_register(&pdev->dev);
1743 if (IS_ERR(hwmon_dev)) { 1279 if (IS_ERR(hwmon_dev)) {
@@ -1745,32 +1281,22 @@ static int __init applesmc_init(void)
1745 goto out_light_ledclass; 1281 goto out_light_ledclass;
1746 } 1282 }
1747 1283
1748 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1749
1750 return 0; 1284 return 0;
1751 1285
1752out_light_ledclass: 1286out_light_ledclass:
1753 if (applesmc_light) 1287 applesmc_release_key_backlight();
1754 led_classdev_unregister(&applesmc_backlight);
1755out_light_wq:
1756 if (applesmc_light)
1757 destroy_workqueue(applesmc_led_wq);
1758out_light_sysfs: 1288out_light_sysfs:
1759 if (applesmc_light) 1289 applesmc_release_light_sensor();
1760 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1761out_accelerometer: 1290out_accelerometer:
1762 if (applesmc_accelerometer) 1291 applesmc_release_accelerometer();
1763 applesmc_release_accelerometer();
1764out_temperature: 1292out_temperature:
1765 sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group); 1293 applesmc_destroy_nodes(temp_group);
1766 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1767out_fans: 1294out_fans:
1768 while (fans_handled) 1295 applesmc_destroy_nodes(fan_group);
1769 sysfs_remove_group(&pdev->dev.kobj, 1296out_info:
1770 &fan_attribute_groups[--fans_handled]); 1297 applesmc_destroy_nodes(info_group);
1771 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); 1298out_smcreg:
1772out_name: 1299 applesmc_destroy_smcreg();
1773 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1774out_device: 1300out_device:
1775 platform_device_unregister(pdev); 1301 platform_device_unregister(pdev);
1776out_driver: 1302out_driver:
@@ -1778,32 +1304,23 @@ out_driver:
1778out_region: 1304out_region:
1779 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); 1305 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1780out: 1306out:
1781 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret); 1307 pr_warn("driver init failed (ret=%d)!\n", ret);
1782 return ret; 1308 return ret;
1783} 1309}
1784 1310
1785static void __exit applesmc_exit(void) 1311static void __exit applesmc_exit(void)
1786{ 1312{
1787 hwmon_device_unregister(hwmon_dev); 1313 hwmon_device_unregister(hwmon_dev);
1788 if (applesmc_light) { 1314 applesmc_release_key_backlight();
1789 led_classdev_unregister(&applesmc_backlight); 1315 applesmc_release_light_sensor();
1790 destroy_workqueue(applesmc_led_wq); 1316 applesmc_release_accelerometer();
1791 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr); 1317 applesmc_destroy_nodes(temp_group);
1792 } 1318 applesmc_destroy_nodes(fan_group);
1793 if (applesmc_accelerometer) 1319 applesmc_destroy_nodes(info_group);
1794 applesmc_release_accelerometer(); 1320 applesmc_destroy_smcreg();
1795 sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group);
1796 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1797 while (fans_handled)
1798 sysfs_remove_group(&pdev->dev.kobj,
1799 &fan_attribute_groups[--fans_handled]);
1800 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1801 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
1802 platform_device_unregister(pdev); 1321 platform_device_unregister(pdev);
1803 platform_driver_unregister(&applesmc_driver); 1322 platform_driver_unregister(&applesmc_driver);
1804 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); 1323 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1805
1806 printk(KERN_INFO "applesmc: driver unloaded.\n");
1807} 1324}
1808 1325
1809module_init(applesmc_init); 1326module_init(applesmc_init);