aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/toshiba_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/toshiba_acpi.c')
-rw-r--r--drivers/acpi/toshiba_acpi.c174
1 files changed, 77 insertions, 97 deletions
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index 73b1d8aeae9d..7fe0b7ae9733 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -100,8 +100,7 @@ MODULE_LICENSE("GPL");
100/* utility 100/* utility
101 */ 101 */
102 102
103static __inline__ void 103static __inline__ void _set_bit(u32 * word, u32 mask, int value)
104_set_bit(u32* word, u32 mask, int value)
105{ 104{
106 *word = (*word & ~mask) | (mask * value); 105 *word = (*word & ~mask) | (mask * value);
107} 106}
@@ -109,35 +108,32 @@ _set_bit(u32* word, u32 mask, int value)
109/* acpi interface wrappers 108/* acpi interface wrappers
110 */ 109 */
111 110
112static int 111static int is_valid_acpi_path(const char *methodName)
113is_valid_acpi_path(const char* methodName)
114{ 112{
115 acpi_handle handle; 113 acpi_handle handle;
116 acpi_status status; 114 acpi_status status;
117 115
118 status = acpi_get_handle(NULL, (char*)methodName, &handle); 116 status = acpi_get_handle(NULL, (char *)methodName, &handle);
119 return !ACPI_FAILURE(status); 117 return !ACPI_FAILURE(status);
120} 118}
121 119
122static int 120static int write_acpi_int(const char *methodName, int val)
123write_acpi_int(const char* methodName, int val)
124{ 121{
125 struct acpi_object_list params; 122 struct acpi_object_list params;
126 union acpi_object in_objs[1]; 123 union acpi_object in_objs[1];
127 acpi_status status; 124 acpi_status status;
128 125
129 params.count = sizeof(in_objs)/sizeof(in_objs[0]); 126 params.count = sizeof(in_objs) / sizeof(in_objs[0]);
130 params.pointer = in_objs; 127 params.pointer = in_objs;
131 in_objs[0].type = ACPI_TYPE_INTEGER; 128 in_objs[0].type = ACPI_TYPE_INTEGER;
132 in_objs[0].integer.value = val; 129 in_objs[0].integer.value = val;
133 130
134 status = acpi_evaluate_object(NULL, (char*)methodName, &params, NULL); 131 status = acpi_evaluate_object(NULL, (char *)methodName, &params, NULL);
135 return (status == AE_OK); 132 return (status == AE_OK);
136} 133}
137 134
138#if 0 135#if 0
139static int 136static int read_acpi_int(const char *methodName, int *pVal)
140read_acpi_int(const char* methodName, int* pVal)
141{ 137{
142 struct acpi_buffer results; 138 struct acpi_buffer results;
143 union acpi_object out_objs[1]; 139 union acpi_object out_objs[1];
@@ -146,25 +142,24 @@ read_acpi_int(const char* methodName, int* pVal)
146 results.length = sizeof(out_objs); 142 results.length = sizeof(out_objs);
147 results.pointer = out_objs; 143 results.pointer = out_objs;
148 144
149 status = acpi_evaluate_object(0, (char*)methodName, 0, &results); 145 status = acpi_evaluate_object(0, (char *)methodName, 0, &results);
150 *pVal = out_objs[0].integer.value; 146 *pVal = out_objs[0].integer.value;
151 147
152 return (status == AE_OK) && (out_objs[0].type == ACPI_TYPE_INTEGER); 148 return (status == AE_OK) && (out_objs[0].type == ACPI_TYPE_INTEGER);
153} 149}
154#endif 150#endif
155 151
156static const char* method_hci /*= 0*/; 152static const char *method_hci /*= 0*/ ;
157 153
158/* Perform a raw HCI call. Here we don't care about input or output buffer 154/* Perform a raw HCI call. Here we don't care about input or output buffer
159 * format. 155 * format.
160 */ 156 */
161static acpi_status 157static acpi_status hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
162hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
163{ 158{
164 struct acpi_object_list params; 159 struct acpi_object_list params;
165 union acpi_object in_objs[HCI_WORDS]; 160 union acpi_object in_objs[HCI_WORDS];
166 struct acpi_buffer results; 161 struct acpi_buffer results;
167 union acpi_object out_objs[HCI_WORDS+1]; 162 union acpi_object out_objs[HCI_WORDS + 1];
168 acpi_status status; 163 acpi_status status;
169 int i; 164 int i;
170 165
@@ -178,8 +173,8 @@ hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
178 results.length = sizeof(out_objs); 173 results.length = sizeof(out_objs);
179 results.pointer = out_objs; 174 results.pointer = out_objs;
180 175
181 status = acpi_evaluate_object(NULL, (char*)method_hci, &params, 176 status = acpi_evaluate_object(NULL, (char *)method_hci, &params,
182 &results); 177 &results);
183 if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) { 178 if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) {
184 for (i = 0; i < out_objs->package.count; ++i) { 179 for (i = 0; i < out_objs->package.count; ++i) {
185 out[i] = out_objs->package.elements[i].integer.value; 180 out[i] = out_objs->package.elements[i].integer.value;
@@ -195,8 +190,7 @@ hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
195 * may be useful (such as "not supported"). 190 * may be useful (such as "not supported").
196 */ 191 */
197 192
198static acpi_status 193static acpi_status hci_write1(u32 reg, u32 in1, u32 * result)
199hci_write1(u32 reg, u32 in1, u32* result)
200{ 194{
201 u32 in[HCI_WORDS] = { HCI_SET, reg, in1, 0, 0, 0 }; 195 u32 in[HCI_WORDS] = { HCI_SET, reg, in1, 0, 0, 0 };
202 u32 out[HCI_WORDS]; 196 u32 out[HCI_WORDS];
@@ -205,8 +199,7 @@ hci_write1(u32 reg, u32 in1, u32* result)
205 return status; 199 return status;
206} 200}
207 201
208static acpi_status 202static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result)
209hci_read1(u32 reg, u32* out1, u32* result)
210{ 203{
211 u32 in[HCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 }; 204 u32 in[HCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 };
212 u32 out[HCI_WORDS]; 205 u32 out[HCI_WORDS];
@@ -216,26 +209,25 @@ hci_read1(u32 reg, u32* out1, u32* result)
216 return status; 209 return status;
217} 210}
218 211
219static struct proc_dir_entry* toshiba_proc_dir /*= 0*/; 212static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
220static int force_fan; 213static int force_fan;
221static int last_key_event; 214static int last_key_event;
222static int key_event_valid; 215static int key_event_valid;
223 216
224typedef struct _ProcItem 217typedef struct _ProcItem {
225{ 218 const char *name;
226 const char* name; 219 char *(*read_func) (char *);
227 char* (*read_func)(char*); 220 unsigned long (*write_func) (const char *, unsigned long);
228 unsigned long (*write_func)(const char*, unsigned long);
229} ProcItem; 221} ProcItem;
230 222
231/* proc file handlers 223/* proc file handlers
232 */ 224 */
233 225
234static int 226static int
235dispatch_read(char* page, char** start, off_t off, int count, int* eof, 227dispatch_read(char *page, char **start, off_t off, int count, int *eof,
236 ProcItem* item) 228 ProcItem * item)
237{ 229{
238 char* p = page; 230 char *p = page;
239 int len; 231 int len;
240 232
241 if (off == 0) 233 if (off == 0)
@@ -243,33 +235,35 @@ dispatch_read(char* page, char** start, off_t off, int count, int* eof,
243 235
244 /* ISSUE: I don't understand this code */ 236 /* ISSUE: I don't understand this code */
245 len = (p - page); 237 len = (p - page);
246 if (len <= off+count) *eof = 1; 238 if (len <= off + count)
239 *eof = 1;
247 *start = page + off; 240 *start = page + off;
248 len -= off; 241 len -= off;
249 if (len>count) len = count; 242 if (len > count)
250 if (len<0) len = 0; 243 len = count;
244 if (len < 0)
245 len = 0;
251 return len; 246 return len;
252} 247}
253 248
254static int 249static int
255dispatch_write(struct file* file, const char __user * buffer, 250dispatch_write(struct file *file, const char __user * buffer,
256 unsigned long count, ProcItem* item) 251 unsigned long count, ProcItem * item)
257{ 252{
258 int result; 253 int result;
259 char* tmp_buffer; 254 char *tmp_buffer;
260 255
261 /* Arg buffer points to userspace memory, which can't be accessed 256 /* Arg buffer points to userspace memory, which can't be accessed
262 * directly. Since we're making a copy, zero-terminate the 257 * directly. Since we're making a copy, zero-terminate the
263 * destination so that sscanf can be used on it safely. 258 * destination so that sscanf can be used on it safely.
264 */ 259 */
265 tmp_buffer = kmalloc(count + 1, GFP_KERNEL); 260 tmp_buffer = kmalloc(count + 1, GFP_KERNEL);
266 if(!tmp_buffer) 261 if (!tmp_buffer)
267 return -ENOMEM; 262 return -ENOMEM;
268 263
269 if (copy_from_user(tmp_buffer, buffer, count)) { 264 if (copy_from_user(tmp_buffer, buffer, count)) {
270 result = -EFAULT; 265 result = -EFAULT;
271 } 266 } else {
272 else {
273 tmp_buffer[count] = 0; 267 tmp_buffer[count] = 0;
274 result = item->write_func(tmp_buffer, count); 268 result = item->write_func(tmp_buffer, count);
275 } 269 }
@@ -277,8 +271,7 @@ dispatch_write(struct file* file, const char __user * buffer,
277 return result; 271 return result;
278} 272}
279 273
280static char* 274static char *read_lcd(char *p)
281read_lcd(char* p)
282{ 275{
283 u32 hci_result; 276 u32 hci_result;
284 u32 value; 277 u32 value;
@@ -288,7 +281,7 @@ read_lcd(char* p)
288 value = value >> HCI_LCD_BRIGHTNESS_SHIFT; 281 value = value >> HCI_LCD_BRIGHTNESS_SHIFT;
289 p += sprintf(p, "brightness: %d\n", value); 282 p += sprintf(p, "brightness: %d\n", value);
290 p += sprintf(p, "brightness_levels: %d\n", 283 p += sprintf(p, "brightness_levels: %d\n",
291 HCI_LCD_BRIGHTNESS_LEVELS); 284 HCI_LCD_BRIGHTNESS_LEVELS);
292 } else { 285 } else {
293 printk(MY_ERR "Error reading LCD brightness\n"); 286 printk(MY_ERR "Error reading LCD brightness\n");
294 } 287 }
@@ -296,14 +289,13 @@ read_lcd(char* p)
296 return p; 289 return p;
297} 290}
298 291
299static unsigned long 292static unsigned long write_lcd(const char *buffer, unsigned long count)
300write_lcd(const char* buffer, unsigned long count)
301{ 293{
302 int value; 294 int value;
303 u32 hci_result; 295 u32 hci_result;
304 296
305 if (sscanf(buffer, " brightness : %i", &value) == 1 && 297 if (sscanf(buffer, " brightness : %i", &value) == 1 &&
306 value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { 298 value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
307 value = value << HCI_LCD_BRIGHTNESS_SHIFT; 299 value = value << HCI_LCD_BRIGHTNESS_SHIFT;
308 hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result); 300 hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result);
309 if (hci_result != HCI_SUCCESS) 301 if (hci_result != HCI_SUCCESS)
@@ -315,8 +307,7 @@ write_lcd(const char* buffer, unsigned long count)
315 return count; 307 return count;
316} 308}
317 309
318static char* 310static char *read_video(char *p)
319read_video(char* p)
320{ 311{
321 u32 hci_result; 312 u32 hci_result;
322 u32 value; 313 u32 value;
@@ -325,7 +316,7 @@ read_video(char* p)
325 if (hci_result == HCI_SUCCESS) { 316 if (hci_result == HCI_SUCCESS) {
326 int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; 317 int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0;
327 int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; 318 int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0;
328 int is_tv = (value & HCI_VIDEO_OUT_TV ) ? 1 : 0; 319 int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0;
329 p += sprintf(p, "lcd_out: %d\n", is_lcd); 320 p += sprintf(p, "lcd_out: %d\n", is_lcd);
330 p += sprintf(p, "crt_out: %d\n", is_crt); 321 p += sprintf(p, "crt_out: %d\n", is_crt);
331 p += sprintf(p, "tv_out: %d\n", is_tv); 322 p += sprintf(p, "tv_out: %d\n", is_tv);
@@ -336,8 +327,7 @@ read_video(char* p)
336 return p; 327 return p;
337} 328}
338 329
339static unsigned long 330static unsigned long write_video(const char *buffer, unsigned long count)
340write_video(const char* buffer, unsigned long count)
341{ 331{
342 int value; 332 int value;
343 int remain = count; 333 int remain = count;
@@ -363,7 +353,7 @@ write_video(const char* buffer, unsigned long count)
363 ++buffer; 353 ++buffer;
364 --remain; 354 --remain;
365 } 355 }
366 while (remain && *(buffer-1) != ';'); 356 while (remain && *(buffer - 1) != ';');
367 } 357 }
368 358
369 hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result); 359 hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result);
@@ -386,8 +376,7 @@ write_video(const char* buffer, unsigned long count)
386 return count; 376 return count;
387} 377}
388 378
389static char* 379static char *read_fan(char *p)
390read_fan(char* p)
391{ 380{
392 u32 hci_result; 381 u32 hci_result;
393 u32 value; 382 u32 value;
@@ -403,14 +392,13 @@ read_fan(char* p)
403 return p; 392 return p;
404} 393}
405 394
406static unsigned long 395static unsigned long write_fan(const char *buffer, unsigned long count)
407write_fan(const char* buffer, unsigned long count)
408{ 396{
409 int value; 397 int value;
410 u32 hci_result; 398 u32 hci_result;
411 399
412 if (sscanf(buffer, " force_on : %i", &value) == 1 && 400 if (sscanf(buffer, " force_on : %i", &value) == 1 &&
413 value >= 0 && value <= 1) { 401 value >= 0 && value <= 1) {
414 hci_write1(HCI_FAN, value, &hci_result); 402 hci_write1(HCI_FAN, value, &hci_result);
415 if (hci_result != HCI_SUCCESS) 403 if (hci_result != HCI_SUCCESS)
416 return -EFAULT; 404 return -EFAULT;
@@ -423,8 +411,7 @@ write_fan(const char* buffer, unsigned long count)
423 return count; 411 return count;
424} 412}
425 413
426static char* 414static char *read_keys(char *p)
427read_keys(char* p)
428{ 415{
429 u32 hci_result; 416 u32 hci_result;
430 u32 value; 417 u32 value;
@@ -451,17 +438,15 @@ read_keys(char* p)
451 p += sprintf(p, "hotkey_ready: %d\n", key_event_valid); 438 p += sprintf(p, "hotkey_ready: %d\n", key_event_valid);
452 p += sprintf(p, "hotkey: 0x%04x\n", last_key_event); 439 p += sprintf(p, "hotkey: 0x%04x\n", last_key_event);
453 440
454end: 441 end:
455 return p; 442 return p;
456} 443}
457 444
458static unsigned long 445static unsigned long write_keys(const char *buffer, unsigned long count)
459write_keys(const char* buffer, unsigned long count)
460{ 446{
461 int value; 447 int value;
462 448
463 if (sscanf(buffer, " hotkey_ready : %i", &value) == 1 && 449 if (sscanf(buffer, " hotkey_ready : %i", &value) == 1 && value == 0) {
464 value == 0) {
465 key_event_valid = 0; 450 key_event_valid = 0;
466 } else { 451 } else {
467 return -EINVAL; 452 return -EINVAL;
@@ -470,12 +455,11 @@ write_keys(const char* buffer, unsigned long count)
470 return count; 455 return count;
471} 456}
472 457
473static char* 458static char *read_version(char *p)
474read_version(char* p)
475{ 459{
476 p += sprintf(p, "driver: %s\n", TOSHIBA_ACPI_VERSION); 460 p += sprintf(p, "driver: %s\n", TOSHIBA_ACPI_VERSION);
477 p += sprintf(p, "proc_interface: %d\n", 461 p += sprintf(p, "proc_interface: %d\n",
478 PROC_INTERFACE_VERSION); 462 PROC_INTERFACE_VERSION);
479 return p; 463 return p;
480} 464}
481 465
@@ -484,48 +468,45 @@ read_version(char* p)
484 468
485#define PROC_TOSHIBA "toshiba" 469#define PROC_TOSHIBA "toshiba"
486 470
487static ProcItem proc_items[] = 471static ProcItem proc_items[] = {
488{ 472 {"lcd", read_lcd, write_lcd},
489 { "lcd" , read_lcd , write_lcd }, 473 {"video", read_video, write_video},
490 { "video" , read_video , write_video }, 474 {"fan", read_fan, write_fan},
491 { "fan" , read_fan , write_fan }, 475 {"keys", read_keys, write_keys},
492 { "keys" , read_keys , write_keys }, 476 {"version", read_version, NULL},
493 { "version" , read_version , NULL }, 477 {NULL}
494 { NULL }
495}; 478};
496 479
497static acpi_status __init 480static acpi_status __init add_device(void)
498add_device(void)
499{ 481{
500 struct proc_dir_entry* proc; 482 struct proc_dir_entry *proc;
501 ProcItem* item; 483 ProcItem *item;
502 484
503 for (item = proc_items; item->name; ++item) 485 for (item = proc_items; item->name; ++item) {
504 {
505 proc = create_proc_read_entry(item->name, 486 proc = create_proc_read_entry(item->name,
506 S_IFREG | S_IRUGO | S_IWUSR, 487 S_IFREG | S_IRUGO | S_IWUSR,
507 toshiba_proc_dir, (read_proc_t*)dispatch_read, item); 488 toshiba_proc_dir,
489 (read_proc_t *) dispatch_read,
490 item);
508 if (proc) 491 if (proc)
509 proc->owner = THIS_MODULE; 492 proc->owner = THIS_MODULE;
510 if (proc && item->write_func) 493 if (proc && item->write_func)
511 proc->write_proc = (write_proc_t*)dispatch_write; 494 proc->write_proc = (write_proc_t *) dispatch_write;
512 } 495 }
513 496
514 return AE_OK; 497 return AE_OK;
515} 498}
516 499
517static acpi_status __exit 500static acpi_status __exit remove_device(void)
518remove_device(void)
519{ 501{
520 ProcItem* item; 502 ProcItem *item;
521 503
522 for (item = proc_items; item->name; ++item) 504 for (item = proc_items; item->name; ++item)
523 remove_proc_entry(item->name, toshiba_proc_dir); 505 remove_proc_entry(item->name, toshiba_proc_dir);
524 return AE_OK; 506 return AE_OK;
525} 507}
526 508
527static int __init 509static int __init toshiba_acpi_init(void)
528toshiba_acpi_init(void)
529{ 510{
530 acpi_status status = AE_OK; 511 acpi_status status = AE_OK;
531 u32 hci_result; 512 u32 hci_result;
@@ -533,9 +514,9 @@ toshiba_acpi_init(void)
533 if (acpi_disabled) 514 if (acpi_disabled)
534 return -ENODEV; 515 return -ENODEV;
535 516
536 if (!acpi_specific_hotkey_enabled){ 517 if (!acpi_specific_hotkey_enabled) {
537 printk(MY_INFO "Using generic hotkey driver\n"); 518 printk(MY_INFO "Using generic hotkey driver\n");
538 return -ENODEV; 519 return -ENODEV;
539 } 520 }
540 /* simple device detection: look for HCI method */ 521 /* simple device detection: look for HCI method */
541 if (is_valid_acpi_path(METHOD_HCI_1)) 522 if (is_valid_acpi_path(METHOD_HCI_1))
@@ -546,7 +527,7 @@ toshiba_acpi_init(void)
546 return -ENODEV; 527 return -ENODEV;
547 528
548 printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n", 529 printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n",
549 TOSHIBA_ACPI_VERSION); 530 TOSHIBA_ACPI_VERSION);
550 printk(MY_INFO " HCI method: %s\n", method_hci); 531 printk(MY_INFO " HCI method: %s\n", method_hci);
551 532
552 force_fan = 0; 533 force_fan = 0;
@@ -568,8 +549,7 @@ toshiba_acpi_init(void)
568 return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; 549 return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
569} 550}
570 551
571static void __exit 552static void __exit toshiba_acpi_exit(void)
572toshiba_acpi_exit(void)
573{ 553{
574 remove_device(); 554 remove_device();
575 555