aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2008-10-22 01:21:51 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-10-22 12:56:37 -0400
commitf2d86100d95274bd85a36b7b7c0efa9af0d82b2b (patch)
tree16f4c8f4b917af2616137815e7748f1b4561d72c /drivers/staging
parentbc36e6559c32374b7f9cf18e9461cd51998c41d3 (diff)
Staging: pcc-acpi: update to latest version
Import the changes from the upstream driver into this version to keep things up to date. Cc: Yokota Hiroshi <yokota@netlab.cs.tsukuba.ac.jp> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/pcc-acpi/pcc-acpi.c540
1 files changed, 309 insertions, 231 deletions
diff --git a/drivers/staging/pcc-acpi/pcc-acpi.c b/drivers/staging/pcc-acpi/pcc-acpi.c
index ffda32a10303..e44181ead26d 100644
--- a/drivers/staging/pcc-acpi/pcc-acpi.c
+++ b/drivers/staging/pcc-acpi/pcc-acpi.c
@@ -94,20 +94,21 @@
94 * 94 *
95 */ 95 */
96 96
97#define ACPI_PCC_VERSION "0.9" 97#define ACPI_PCC_VERSION "0.9+hy"
98 98
99#include <linux/version.h> 99#include <acpi/acpi_bus.h>
100#include <acpi/acpi_drivers.h>
101#include <asm/uaccess.h>
102#include <linux/ctype.h>
103#include <linux/init.h>
104#include <linux/input.h>
100#include <linux/kernel.h> 105#include <linux/kernel.h>
101#include <linux/module.h> 106#include <linux/module.h>
102#include <linux/init.h>
103#include <linux/types.h>
104#include <linux/proc_fs.h> 107#include <linux/proc_fs.h>
105#include <linux/ctype.h>
106#include <linux/seq_file.h> 108#include <linux/seq_file.h>
107#include <asm/uaccess.h> 109#include <linux/slab.h>
108#include <acpi/acpi_bus.h> 110#include <linux/types.h>
109#include <acpi/acpi_drivers.h> 111#include <linux/version.h>
110#include <linux/input.h>
111 112
112 113
113/************************************************************************* 114/*************************************************************************
@@ -152,10 +153,10 @@ static int _open_func_name_(struct inode *inode, struct file *file) \
152#endif 153#endif
153 154
154#define _COMPONENT ACPI_HOTKEY_COMPONENT 155#define _COMPONENT ACPI_HOTKEY_COMPONENT
155ACPI_MODULE_NAME("pcc_acpi") 156ACPI_MODULE_NAME("pcc_acpi");
156 157
157MODULE_AUTHOR("Hiroshi Miura"); 158MODULE_AUTHOR("Hiroshi Miura, Hiroshi Yokota");
158MODULE_DESCRIPTION("ACPI HotKey driver for Panasonic Lets Note laptops"); 159MODULE_DESCRIPTION("ACPI HotKey driver for Panasonic Let's Note laptops");
159MODULE_LICENSE("GPL"); 160MODULE_LICENSE("GPL");
160 161
161#define LOGPREFIX "pcc_acpi: " 162#define LOGPREFIX "pcc_acpi: "
@@ -182,7 +183,7 @@ MODULE_LICENSE("GPL");
182 * definitions for /proc/ interface 183 * definitions for /proc/ interface
183 * 184 *
184 *******************************************************************/ 185 *******************************************************************/
185#define ACPI_PCC_DRIVER_NAME "PCC Extra Driver" 186#define ACPI_PCC_DRIVER_NAME "pcc_acpi"
186#define ACPI_PCC_DEVICE_NAME "PCCExtra" 187#define ACPI_PCC_DEVICE_NAME "PCCExtra"
187#define ACPI_PCC_CLASS "pcc" 188#define ACPI_PCC_CLASS "pcc"
188#define PROC_PCC ACPI_PCC_CLASS 189#define PROC_PCC ACPI_PCC_CLASS
@@ -196,6 +197,12 @@ MODULE_LICENSE("GPL");
196 197
197#define PROC_STR_MAX_LEN 8 198#define PROC_STR_MAX_LEN 8
198 199
200#define BUS_PCC_HOTKEY BUS_I8042 /*0x1a*/ /* FIXME: BUS_I8042? */
201
202/* Fn+F4/F5 confricts with Shift+F1/F2 */
203/* This hack avoids key number confrict */
204#define PCC_KEYINPUT_MODE (0)
205
199/* LCD_TYPEs: 0 = Normal, 1 = Semi-transparent 206/* LCD_TYPEs: 0 = Normal, 1 = Semi-transparent
200 ENV_STATEs: Normal temp=0x01, High temp=0x81, N/A=0x00 207 ENV_STATEs: Normal temp=0x01, High temp=0x81, N/A=0x00
201*/ 208*/
@@ -209,27 +216,32 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0,
209 SINF_STICKY_KEY = 0x80, 216 SINF_STICKY_KEY = 0x80,
210}; 217};
211 218
212static int acpi_pcc_hotkey_add(struct acpi_device *device); 219static struct acpi_device_id pcc_device_ids[] = {
213static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type);
214static int acpi_pcc_hotkey_resume(struct acpi_device *device);
215
216static const struct acpi_device_id pcc_device_ids[] = {
217 {"MAT0012", 0}, 220 {"MAT0012", 0},
218 {"MAT0013", 0}, 221 {"MAT0013", 0},
219 {"MAT0018", 0}, 222 {"MAT0018", 0},
220 {"MAT0019", 0}, 223 {"MAT0019", 0},
221 {"", 0}, 224 {"", 0},
222}; 225};
223MODULE_DEVICE_TABLE(acpi, pcc_device_ids); 226MODULE_DEVICE_TABLE(acpi, pcc_device_ids);
224 227
228
229static int __devinit acpi_pcc_hotkey_add(struct acpi_device *device);
230static int __devexit acpi_pcc_hotkey_remove(struct acpi_device *device, int type);
231static int acpi_pcc_hotkey_resume(struct acpi_device *device);
232
233
225static struct acpi_driver acpi_pcc_driver = { 234static struct acpi_driver acpi_pcc_driver = {
226 .name = ACPI_PCC_DRIVER_NAME, 235 .name = ACPI_PCC_DRIVER_NAME,
227 .class = ACPI_PCC_CLASS, 236 .class = ACPI_PCC_CLASS,
228 .ids = pcc_device_ids, 237 .ids = pcc_device_ids,
229 .ops = { 238 .ops = {
230 .add = acpi_pcc_hotkey_add, 239 .add = acpi_pcc_hotkey_add,
231 .remove = acpi_pcc_hotkey_remove, 240 .remove = __devexit_p(acpi_pcc_hotkey_remove),
241#ifdef CONFIG_PM
242 /*.suspend = acpi_pcc_hotkey_suspend,*/
232 .resume = acpi_pcc_hotkey_resume, 243 .resume = acpi_pcc_hotkey_resume,
244#endif
233 }, 245 },
234}; 246};
235 247
@@ -248,9 +260,12 @@ struct pcc_keyinput {
248 int key_mode; 260 int key_mode;
249}; 261};
250 262
251/* -------------------------------------------------------------------------- 263/* *************************************************************************
264 Hotkey driver core
265 ************************************************************************* */
266/* -------------------------------------------------------------------------
252 method access functions 267 method access functions
253 -------------------------------------------------------------------------- */ 268 ------------------------------------------------------------------------- */
254static int acpi_pcc_write_sset(struct acpi_hotkey *hotkey, int func, int val) 269static int acpi_pcc_write_sset(struct acpi_hotkey *hotkey, int func, int val)
255{ 270{
256 union acpi_object in_objs[] = { 271 union acpi_object in_objs[] = {
@@ -263,13 +278,13 @@ static int acpi_pcc_write_sset(struct acpi_hotkey *hotkey, int func, int val)
263 .count = ARRAY_SIZE(in_objs), 278 .count = ARRAY_SIZE(in_objs),
264 .pointer = in_objs, 279 .pointer = in_objs,
265 }; 280 };
266 acpi_status status = AE_OK; 281 acpi_status status;
267 282
268 ACPI_FUNCTION_TRACE("acpi_pcc_write_sset"); 283 ACPI_FUNCTION_TRACE("acpi_pcc_write_sset");
269 284
270 status = acpi_evaluate_object(hotkey->handle, METHOD_HKEY_SSET, &params, NULL); 285 status = acpi_evaluate_object(hotkey->handle, METHOD_HKEY_SSET, &params, NULL);
271 286
272 return_VALUE(status == AE_OK); 287 return_VALUE(status == AE_OK ? AE_OK : AE_ERROR);
273} 288}
274 289
275static inline int acpi_pcc_get_sqty(struct acpi_device *device) 290static inline int acpi_pcc_get_sqty(struct acpi_device *device)
@@ -301,19 +316,20 @@ static int acpi_pcc_retrieve_biosdata(struct acpi_hotkey *hotkey, u32* sinf)
301 status = acpi_evaluate_object(hotkey->handle, METHOD_HKEY_SINF, 0 , &buffer); 316 status = acpi_evaluate_object(hotkey->handle, METHOD_HKEY_SINF, 0 , &buffer);
302 if (ACPI_FAILURE(status)) { 317 if (ACPI_FAILURE(status)) {
303 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "evaluation error HKEY.SINF\n")); 318 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "evaluation error HKEY.SINF\n"));
304 return_VALUE(0); 319 status = AE_ERROR;
320 return_VALUE(status);
305 } 321 }
306 322
307 hkey = buffer.pointer; 323 hkey = buffer.pointer;
308 if (!hkey || (hkey->type != ACPI_TYPE_PACKAGE)) { 324 if (!hkey || (hkey->type != ACPI_TYPE_PACKAGE)) {
309 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid HKEY.SINF\n")); 325 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid HKEY.SINF\n"));
310 goto end; 326 goto free_buffer;
311 } 327 }
312 328
313 if (hotkey->num_sifr < hkey->package.count) { 329 if (hotkey->num_sifr < hkey->package.count) {
314 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "SQTY reports bad SINF length\n")); 330 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "SQTY reports bad SINF length\n"));
315 status = AE_ERROR; 331 status = AE_ERROR;
316 goto end; 332 goto free_buffer;
317 } 333 }
318 334
319 for (i = 0; i < hkey->package.count; i++) { 335 for (i = 0; i < hkey->package.count; i++) {
@@ -322,59 +338,54 @@ static int acpi_pcc_retrieve_biosdata(struct acpi_hotkey *hotkey, u32* sinf)
322 sinf[i] = element->integer.value; 338 sinf[i] = element->integer.value;
323 } else { 339 } else {
324 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid HKEY.SINF data\n")); 340 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid HKEY.SINF data\n"));
341 status = AE_ERROR;
342 break;
325 } 343 }
326 } 344 }
327 sinf[hkey->package.count] = -1; 345 sinf[hkey->package.count] = -1;
328 346
329end: 347 free_buffer:
330 kfree(buffer.pointer); 348 kfree(buffer.pointer);
331 return_VALUE(status == AE_OK); 349 return_VALUE(status == AE_OK ? AE_OK : AE_ERROR);
332} 350}
333 351
334static int acpi_pcc_read_sinf_field(struct seq_file *seq, int field) 352static int acpi_pcc_read_sinf_field(struct seq_file *seq, int field)
335{ 353{
336 struct acpi_hotkey *hotkey = (struct acpi_hotkey *) seq->private; 354 struct acpi_hotkey *hotkey = (struct acpi_hotkey *) seq->private;
337 u32* sinf = kmalloc(sizeof(u32) * (hotkey->num_sifr + 1), GFP_KERNEL); 355 u32 sinf[hotkey->num_sifr + 1];
338 356
339 ACPI_FUNCTION_TRACE("acpi_pcc_read_sinf_field"); 357 ACPI_FUNCTION_TRACE("acpi_pcc_read_sinf_field");
340 358
341 if (!sinf) { 359 if (ACPI_SUCCESS(acpi_pcc_retrieve_biosdata(hotkey, sinf))) {
342 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't allocate %li bytes\n",
343 sizeof(u32) * hotkey->num_sifr));
344 return_VALUE(0);
345 }
346
347 if (acpi_pcc_retrieve_biosdata(hotkey, sinf)) {
348 seq_printf(seq, "%u\n", sinf[field]); 360 seq_printf(seq, "%u\n", sinf[field]);
349 } else { 361 } else {
350 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't retrieve BIOS data\n")); 362 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't retrieve BIOS data\n"));
351 } 363 }
352 364
353 kfree(sinf); 365 return_VALUE(AE_OK);
354 return_VALUE(0);
355} 366}
356 367
357/* -------------------------------------------------------------------------- 368/* -------------------------------------------------------------------------
358 user interface functions 369 user interface functions
359 -------------------------------------------------------------------------- */ 370 ------------------------------------------------------------------------- */
360/* read methods */ 371/* read methods */
361/* Sinf read methods */ 372/* Sinf read methods */
362#define PCC_SINF_READ_F(_name_, FUNC) \ 373#define PCC_SINF_READ_F(_name_, FUNC) \
363static int _name_ (struct seq_file *seq, void *offset) \ 374static int _name_ (struct seq_file *seq, void *offset) \
364{ \ 375{ \
365 return acpi_pcc_read_sinf_field(seq, (FUNC)); \ 376 return_VALUE(ACPI_SUCCESS(acpi_pcc_read_sinf_field(seq, (FUNC))) ? 0 : -EINVAL); \
366} 377}
367 378
368PCC_SINF_READ_F(acpi_pcc_numbatteries_show, SINF_NUM_BATTERIES); 379PCC_SINF_READ_F(acpi_pcc_numbatteries_show, SINF_NUM_BATTERIES);
369PCC_SINF_READ_F(acpi_pcc_lcdtype_show, SINF_LCD_TYPE); 380PCC_SINF_READ_F(acpi_pcc_lcdtype_show, SINF_LCD_TYPE);
370PCC_SINF_READ_F(acpi_pcc_ac_brightness_max_show, SINF_AC_MAX_BRIGHT); 381PCC_SINF_READ_F(acpi_pcc_ac_brightness_max_show, SINF_AC_MAX_BRIGHT);
371PCC_SINF_READ_F(acpi_pcc_ac_brightness_min_show, SINF_AC_MIN_BRIGHT); 382PCC_SINF_READ_F(acpi_pcc_ac_brightness_min_show, SINF_AC_MIN_BRIGHT);
372PCC_SINF_READ_F(acpi_pcc_ac_brightness_show, SINF_AC_CUR_BRIGHT); 383PCC_SINF_READ_F(acpi_pcc_ac_brightness_show, SINF_AC_CUR_BRIGHT);
373PCC_SINF_READ_F(acpi_pcc_dc_brightness_max_show, SINF_DC_MAX_BRIGHT); 384PCC_SINF_READ_F(acpi_pcc_dc_brightness_max_show, SINF_DC_MAX_BRIGHT);
374PCC_SINF_READ_F(acpi_pcc_dc_brightness_min_show, SINF_DC_MIN_BRIGHT); 385PCC_SINF_READ_F(acpi_pcc_dc_brightness_min_show, SINF_DC_MIN_BRIGHT);
375PCC_SINF_READ_F(acpi_pcc_dc_brightness_show, SINF_DC_CUR_BRIGHT); 386PCC_SINF_READ_F(acpi_pcc_dc_brightness_show, SINF_DC_CUR_BRIGHT);
376PCC_SINF_READ_F(acpi_pcc_brightness_show, SINF_AC_CUR_BRIGHT); 387PCC_SINF_READ_F(acpi_pcc_brightness_show, SINF_AC_CUR_BRIGHT);
377PCC_SINF_READ_F(acpi_pcc_mute_show, SINF_MUTE); 388PCC_SINF_READ_F(acpi_pcc_mute_show, SINF_MUTE);
378 389
379static int acpi_pcc_sticky_key_show(struct seq_file *seq, void *offset) 390static int acpi_pcc_sticky_key_show(struct seq_file *seq, void *offset)
380{ 391{
@@ -383,7 +394,7 @@ static int acpi_pcc_sticky_key_show(struct seq_file *seq, void *offset)
383 ACPI_FUNCTION_TRACE("acpi_pcc_sticky_key_show"); 394 ACPI_FUNCTION_TRACE("acpi_pcc_sticky_key_show");
384 395
385 if (!hotkey || !hotkey->device) { 396 if (!hotkey || !hotkey->device) {
386 return_VALUE(0); 397 return_VALUE(-EINVAL);
387 } 398 }
388 399
389 seq_printf(seq, "%d\n", hotkey->sticky_mode); 400 seq_printf(seq, "%d\n", hotkey->sticky_mode);
@@ -410,8 +421,9 @@ static int acpi_pcc_version_show(struct seq_file *seq, void *offset)
410 421
411 ACPI_FUNCTION_TRACE("acpi_pcc_version_show"); 422 ACPI_FUNCTION_TRACE("acpi_pcc_version_show");
412 423
413 if (!hotkey || !hotkey->device) 424 if (!hotkey || !hotkey->device) {
414 return 0; 425 return_VALUE(-EINVAL);
426 }
415 427
416 seq_printf(seq, "%s version %s\n", ACPI_PCC_DRIVER_NAME, ACPI_PCC_VERSION); 428 seq_printf(seq, "%s version %s\n", ACPI_PCC_DRIVER_NAME, ACPI_PCC_VERSION);
417 seq_printf(seq, "%li functions\n", hotkey->num_sifr); 429 seq_printf(seq, "%li functions\n", hotkey->num_sifr);
@@ -421,27 +433,28 @@ static int acpi_pcc_version_show(struct seq_file *seq, void *offset)
421 433
422/* write methods */ 434/* write methods */
423static ssize_t acpi_pcc_write_single_flag (struct file *file, 435static ssize_t acpi_pcc_write_single_flag (struct file *file,
424 const char __user *buffer, 436 const char __user *buffer,
425 size_t count, 437 size_t count,
426 int sinf_func) 438 int sinf_func)
427{ 439{
428 struct seq_file *seq = file->private_data; 440 struct seq_file *seq = file->private_data;
429 struct acpi_hotkey *hotkey = seq->private; 441 struct acpi_hotkey *hotkey = seq->private;
430 char write_string[PROC_STR_MAX_LEN]; 442 char write_string[PROC_STR_MAX_LEN];
431 u32 val; 443 u32 val;
432 444
433 ACPI_FUNCTION_TRACE("acpi_pcc_write_single_flag"); 445 ACPI_FUNCTION_TRACE("acpi_pcc_write_single_flag");
434 446
435 if (!hotkey || (count > sizeof(write_string) - 1)) { 447 if (!hotkey || (count > sizeof(write_string) - 1)) {
436 return_VALUE(-EINVAL); 448 return_VALUE(-EINVAL);
437 } 449 }
438 450
439 if (copy_from_user(write_string, buffer, count)) { 451 if (copy_from_user(write_string, buffer, count)) {
440 return_VALUE(-EFAULT); 452 return_VALUE(-EFAULT);
441 } 453 }
442 write_string[count] = '\0'; 454 write_string[count] = '\0';
443 455
444 if (sscanf(write_string, "%i", &val) == 1 && (val == 0 || val == 1)) { 456 if ((sscanf(write_string, "%3i", &val) == 1) &&
457 (val == 0 || val == 1)) {
445 acpi_pcc_write_sset(hotkey, sinf_func, val); 458 acpi_pcc_write_sset(hotkey, sinf_func, val);
446 } 459 }
447 460
@@ -457,53 +470,51 @@ static unsigned long acpi_pcc_write_brightness(struct file *file, const char __u
457 struct acpi_hotkey *hotkey = (struct acpi_hotkey *)seq->private; 470 struct acpi_hotkey *hotkey = (struct acpi_hotkey *)seq->private;
458 char write_string[PROC_STR_MAX_LEN]; 471 char write_string[PROC_STR_MAX_LEN];
459 u32 bright; 472 u32 bright;
460 u32* sinf = kmalloc(sizeof(u32) * (hotkey->num_sifr + 1), GFP_KERNEL); 473 u32 sinf[hotkey->num_sifr + 1];
461 474
462 ACPI_FUNCTION_TRACE("acpi_pcc_write_brightness"); 475 ACPI_FUNCTION_TRACE("acpi_pcc_write_brightness");
463 476
464 if (!hotkey || (count > sizeof(write_string) - 1)) 477 if (!hotkey || (count > sizeof(write_string) - 1)) {
465 return_VALUE(-EINVAL); 478 return_VALUE(-EINVAL);
466
467 if (!sinf) {
468 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't allocate %li bytes\n",
469 sizeof(u32) * hotkey->num_sifr));
470 return_VALUE(-EFAULT);
471 } 479 }
472 480
473 if (copy_from_user(write_string, buffer, count)) 481 if (copy_from_user(write_string, buffer, count)) {
474 return_VALUE(-EFAULT); 482 return_VALUE(-EFAULT);
483 }
475 484
476 write_string[count] = '\0'; 485 write_string[count] = '\0';
477 486
478 if (!acpi_pcc_retrieve_biosdata(hotkey, sinf)) { 487 if (ACPI_FAILURE(acpi_pcc_retrieve_biosdata(hotkey, sinf))) {
479 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't retrieve BIOS data\n")); 488 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't retrieve BIOS data\n"));
480 goto end; 489 goto end;
481 } 490 }
482 491
483 if (sscanf(write_string, "%i", &bright) == 1 && 492 if ((sscanf(write_string, "%4i", &bright) == 1) &&
484 bright >= sinf[min_index] && bright <= sinf[max_index]) { 493 (bright >= sinf[min_index] ) &&
485 acpi_pcc_write_sset(hotkey, cur_index, bright); 494 (bright <= sinf[max_index] )) {
495 acpi_pcc_write_sset(hotkey, cur_index, bright);
486 } 496 }
487 497
488end: 498end:
489 kfree(sinf);
490 return_VALUE(count); 499 return_VALUE(count);
491} 500}
492 501
493static ssize_t acpi_pcc_write_ac_brightness(struct file *file, const char __user *buffer, 502static ssize_t acpi_pcc_write_ac_brightness(struct file *file, const char __user *buffer,
494 size_t count, loff_t *ppos) 503 size_t count, loff_t *ppos)
495{ 504{
496 return acpi_pcc_write_brightness(file, buffer, count, SINF_AC_MIN_BRIGHT, 505 return_VALUE(acpi_pcc_write_brightness(file, buffer, count,
497 SINF_AC_MAX_BRIGHT, 506 SINF_AC_MIN_BRIGHT,
498 SINF_AC_CUR_BRIGHT); 507 SINF_AC_MAX_BRIGHT,
508 SINF_AC_CUR_BRIGHT));
499} 509}
500 510
501static ssize_t acpi_pcc_write_dc_brightness(struct file *file, const char __user *buffer, 511static ssize_t acpi_pcc_write_dc_brightness(struct file *file, const char __user *buffer,
502 size_t count, loff_t *ppos) 512 size_t count, loff_t *ppos)
503{ 513{
504 return acpi_pcc_write_brightness(file, buffer, count, SINF_DC_MIN_BRIGHT, 514 return_VALUE(acpi_pcc_write_brightness(file, buffer, count,
505 SINF_DC_MAX_BRIGHT, 515 SINF_DC_MIN_BRIGHT,
506 SINF_DC_CUR_BRIGHT); 516 SINF_DC_MAX_BRIGHT,
517 SINF_DC_CUR_BRIGHT));
507} 518}
508 519
509static ssize_t acpi_pcc_write_no_brightness(struct file *file, const char __user *buffer, 520static ssize_t acpi_pcc_write_no_brightness(struct file *file, const char __user *buffer,
@@ -518,14 +529,36 @@ static ssize_t acpi_pcc_write_mute (struct file *file,
518 const char __user *buffer, 529 const char __user *buffer,
519 size_t count, loff_t *ppos) 530 size_t count, loff_t *ppos)
520{ 531{
521 return acpi_pcc_write_single_flag(file, buffer, count, SINF_MUTE); 532 return_VALUE(acpi_pcc_write_single_flag(file, buffer, count, SINF_MUTE));
522} 533}
523 534
524static ssize_t acpi_pcc_write_sticky_key (struct file *file, 535static ssize_t acpi_pcc_write_sticky_key (struct file *file,
525 const char __user *buffer, 536 const char __user *buffer,
526 size_t count, loff_t *ppos) 537 size_t count, loff_t *ppos)
527{ 538{
528 return acpi_pcc_write_single_flag(file, buffer, count, SINF_STICKY_KEY); 539 struct seq_file *seq = (struct seq_file *)file->private_data;
540 struct acpi_hotkey *hotkey = (struct acpi_hotkey *)seq->private;
541 char write_string[PROC_STR_MAX_LEN];
542 int mode;
543
544 ACPI_FUNCTION_TRACE("acpi_pcc_write_sticky_key");
545
546 if (!hotkey || (count > sizeof(write_string) - 1)) {
547 return_VALUE(-EINVAL);
548 }
549
550 if (copy_from_user(write_string, buffer, count)) {
551 return_VALUE(-EFAULT);
552 }
553 write_string[count] = '\0';
554
555 if ((sscanf(write_string, "%3i", &mode) == 1) &&
556 (mode == 0 || mode == 1)) {
557 acpi_pcc_write_sset(hotkey, SINF_STICKY_KEY, mode);
558 hotkey->sticky_mode = mode;
559 }
560
561 return_VALUE(count);
529} 562}
530 563
531static ssize_t acpi_pcc_write_keyinput(struct file *file, const char __user *buffer, 564static ssize_t acpi_pcc_write_keyinput(struct file *file, const char __user *buffer,
@@ -539,25 +572,28 @@ static ssize_t acpi_pcc_write_keyinput(struct file *file, const char __user *buf
539 572
540 ACPI_FUNCTION_TRACE("acpi_pcc_write_keyinput"); 573 ACPI_FUNCTION_TRACE("acpi_pcc_write_keyinput");
541 574
542 if (!hotkey || (count > sizeof(write_string) - 1)) 575 if (!hotkey || (count > (sizeof(write_string) - 1))) {
543 return_VALUE(-EINVAL); 576 return_VALUE(-EINVAL);
577 }
544 578
545 if (copy_from_user(write_string, buffer, count)) 579 if (copy_from_user(write_string, buffer, count)) {
546 return_VALUE(-EFAULT); 580 return_VALUE(-EFAULT);
581 }
547 582
548 write_string[count] = '\0'; 583 write_string[count] = '\0';
549 584
550 if (sscanf(write_string, "%i", &key_mode) == 1 && (key_mode == 0 || key_mode == 1)) { 585 if ((sscanf(write_string, "%4i", &key_mode) == 1) &&
551 keyinput = (struct pcc_keyinput *)input_get_drvdata(hotkey->input_dev); 586 (key_mode == 0 || key_mode == 1)) {
587 keyinput = input_get_drvdata(hotkey->input_dev);
552 keyinput->key_mode = key_mode; 588 keyinput->key_mode = key_mode;
553 } 589 }
554 590
555 return_VALUE(count); 591 return_VALUE(count);
556} 592}
557 593
558/* -------------------------------------------------------------------------- 594/* -------------------------------------------------------------------------
559 hotkey driver 595 hotkey driver
560 -------------------------------------------------------------------------- */ 596 ------------------------------------------------------------------------- */
561static void acpi_pcc_generete_keyinput(struct acpi_hotkey *hotkey) 597static void acpi_pcc_generete_keyinput(struct acpi_hotkey *hotkey)
562{ 598{
563 struct input_dev *hotk_input_dev = hotkey->input_dev; 599 struct input_dev *hotk_input_dev = hotkey->input_dev;
@@ -640,38 +676,38 @@ void acpi_pcc_hotkey_notify(acpi_handle handle, u32 event, void *data)
640 return_VOID; 676 return_VOID;
641} 677}
642 678
643/* -------------------------------------------------------------------------- 679/* *************************************************************************
644 FS Interface (/proc) 680 FS Interface (/proc)
645 -------------------------------------------------------------------------- */ 681 ************************************************************************* */
646/* oepn proc file fs*/ 682/* oepn proc file fs*/
647SEQ_OPEN_FS(acpi_pcc_dc_brightness_open_fs, acpi_pcc_dc_brightness_show); 683SEQ_OPEN_FS(acpi_pcc_dc_brightness_open_fs, acpi_pcc_dc_brightness_show);
648SEQ_OPEN_FS(acpi_pcc_numbatteries_open_fs, acpi_pcc_numbatteries_show); 684SEQ_OPEN_FS(acpi_pcc_numbatteries_open_fs, acpi_pcc_numbatteries_show);
649SEQ_OPEN_FS(acpi_pcc_lcdtype_open_fs, acpi_pcc_lcdtype_show); 685SEQ_OPEN_FS(acpi_pcc_lcdtype_open_fs, acpi_pcc_lcdtype_show);
650SEQ_OPEN_FS(acpi_pcc_ac_brightness_max_open_fs, acpi_pcc_ac_brightness_max_show); 686SEQ_OPEN_FS(acpi_pcc_ac_brightness_max_open_fs, acpi_pcc_ac_brightness_max_show);
651SEQ_OPEN_FS(acpi_pcc_ac_brightness_min_open_fs, acpi_pcc_ac_brightness_min_show); 687SEQ_OPEN_FS(acpi_pcc_ac_brightness_min_open_fs, acpi_pcc_ac_brightness_min_show);
652SEQ_OPEN_FS(acpi_pcc_ac_brightness_open_fs, acpi_pcc_ac_brightness_show); 688SEQ_OPEN_FS(acpi_pcc_ac_brightness_open_fs, acpi_pcc_ac_brightness_show);
653SEQ_OPEN_FS(acpi_pcc_dc_brightness_max_open_fs, acpi_pcc_dc_brightness_max_show); 689SEQ_OPEN_FS(acpi_pcc_dc_brightness_max_open_fs, acpi_pcc_dc_brightness_max_show);
654SEQ_OPEN_FS(acpi_pcc_dc_brightness_min_open_fs, acpi_pcc_dc_brightness_min_show); 690SEQ_OPEN_FS(acpi_pcc_dc_brightness_min_open_fs, acpi_pcc_dc_brightness_min_show);
655SEQ_OPEN_FS(acpi_pcc_brightness_open_fs, acpi_pcc_brightness_show); 691SEQ_OPEN_FS(acpi_pcc_brightness_open_fs, acpi_pcc_brightness_show);
656SEQ_OPEN_FS(acpi_pcc_mute_open_fs, acpi_pcc_mute_show); 692SEQ_OPEN_FS(acpi_pcc_mute_open_fs, acpi_pcc_mute_show);
657SEQ_OPEN_FS(acpi_pcc_version_open_fs, acpi_pcc_version_show); 693SEQ_OPEN_FS(acpi_pcc_version_open_fs, acpi_pcc_version_show);
658SEQ_OPEN_FS(acpi_pcc_keyinput_open_fs, acpi_pcc_keyinput_show); 694SEQ_OPEN_FS(acpi_pcc_keyinput_open_fs, acpi_pcc_keyinput_show);
659SEQ_OPEN_FS(acpi_pcc_sticky_key_open_fs, acpi_pcc_sticky_key_show); 695SEQ_OPEN_FS(acpi_pcc_sticky_key_open_fs, acpi_pcc_sticky_key_show);
660 696
661typedef struct file_operations fops_t; 697typedef struct file_operations fops_t;
662static fops_t acpi_pcc_numbatteries_fops = SEQ_FILEOPS_R (acpi_pcc_numbatteries_open_fs); 698static fops_t acpi_pcc_numbatteries_fops = SEQ_FILEOPS_R (acpi_pcc_numbatteries_open_fs);
663static fops_t acpi_pcc_lcdtype_fops = SEQ_FILEOPS_R (acpi_pcc_lcdtype_open_fs); 699static fops_t acpi_pcc_lcdtype_fops = SEQ_FILEOPS_R (acpi_pcc_lcdtype_open_fs);
664static fops_t acpi_pcc_mute_fops = SEQ_FILEOPS_RW(acpi_pcc_mute_open_fs, acpi_pcc_write_mute); 700static fops_t acpi_pcc_mute_fops = SEQ_FILEOPS_RW(acpi_pcc_mute_open_fs, acpi_pcc_write_mute);
665static fops_t acpi_pcc_ac_brightness_fops = SEQ_FILEOPS_RW(acpi_pcc_ac_brightness_open_fs, acpi_pcc_write_ac_brightness); 701static fops_t acpi_pcc_ac_brightness_fops = SEQ_FILEOPS_RW(acpi_pcc_ac_brightness_open_fs, acpi_pcc_write_ac_brightness);
666static fops_t acpi_pcc_ac_brightness_max_fops = SEQ_FILEOPS_R(acpi_pcc_ac_brightness_max_open_fs); 702static fops_t acpi_pcc_ac_brightness_max_fops = SEQ_FILEOPS_R (acpi_pcc_ac_brightness_max_open_fs);
667static fops_t acpi_pcc_ac_brightness_min_fops = SEQ_FILEOPS_R(acpi_pcc_ac_brightness_min_open_fs); 703static fops_t acpi_pcc_ac_brightness_min_fops = SEQ_FILEOPS_R (acpi_pcc_ac_brightness_min_open_fs);
668static fops_t acpi_pcc_dc_brightness_fops = SEQ_FILEOPS_RW(acpi_pcc_dc_brightness_open_fs, acpi_pcc_write_dc_brightness); 704static fops_t acpi_pcc_dc_brightness_fops = SEQ_FILEOPS_RW(acpi_pcc_dc_brightness_open_fs, acpi_pcc_write_dc_brightness);
669static fops_t acpi_pcc_dc_brightness_max_fops = SEQ_FILEOPS_R(acpi_pcc_dc_brightness_max_open_fs); 705static fops_t acpi_pcc_dc_brightness_max_fops = SEQ_FILEOPS_R (acpi_pcc_dc_brightness_max_open_fs);
670static fops_t acpi_pcc_dc_brightness_min_fops = SEQ_FILEOPS_R(acpi_pcc_dc_brightness_min_open_fs); 706static fops_t acpi_pcc_dc_brightness_min_fops = SEQ_FILEOPS_R (acpi_pcc_dc_brightness_min_open_fs);
671static fops_t acpi_pcc_brightness_fops = SEQ_FILEOPS_RW(acpi_pcc_brightness_open_fs, acpi_pcc_write_no_brightness); 707static fops_t acpi_pcc_brightness_fops = SEQ_FILEOPS_RW(acpi_pcc_brightness_open_fs, acpi_pcc_write_no_brightness);
672static fops_t acpi_pcc_sticky_key_fops = SEQ_FILEOPS_RW(acpi_pcc_sticky_key_open_fs, acpi_pcc_write_sticky_key); 708static fops_t acpi_pcc_sticky_key_fops = SEQ_FILEOPS_RW(acpi_pcc_sticky_key_open_fs, acpi_pcc_write_sticky_key);
673static fops_t acpi_pcc_keyinput_fops = SEQ_FILEOPS_RW(acpi_pcc_keyinput_open_fs, acpi_pcc_write_keyinput); 709static fops_t acpi_pcc_keyinput_fops = SEQ_FILEOPS_RW(acpi_pcc_keyinput_open_fs, acpi_pcc_write_keyinput);
674static fops_t acpi_pcc_version_fops = SEQ_FILEOPS_R (acpi_pcc_version_open_fs); 710static fops_t acpi_pcc_version_fops = SEQ_FILEOPS_R (acpi_pcc_version_open_fs);
675 711
676typedef struct _ProcItem 712typedef struct _ProcItem
677{ 713{
@@ -681,37 +717,35 @@ typedef struct _ProcItem
681} ProcItem; 717} ProcItem;
682 718
683/* Note: These functions map *exactly* to the SINF/SSET functions */ 719/* Note: These functions map *exactly* to the SINF/SSET functions */
684ProcItem pcc_proc_items_sifr[] = 720ProcItem acpi_pcc_proc_items_sifr[] = {
685{ 721 { "num_batteries", &acpi_pcc_numbatteries_fops, S_IRUGO },
686 { "num_batteries", &acpi_pcc_numbatteries_fops, S_IRUGO }, 722 { "lcd_type", &acpi_pcc_lcdtype_fops, S_IRUGO },
687 { "lcd_type", &acpi_pcc_lcdtype_fops, S_IRUGO },
688 { "ac_brightness_max" , &acpi_pcc_ac_brightness_max_fops,S_IRUGO }, 723 { "ac_brightness_max" , &acpi_pcc_ac_brightness_max_fops,S_IRUGO },
689 { "ac_brightness_min" , &acpi_pcc_ac_brightness_min_fops,S_IRUGO }, 724 { "ac_brightness_min" , &acpi_pcc_ac_brightness_min_fops,S_IRUGO },
690 { "ac_brightness" , &acpi_pcc_ac_brightness_fops, S_IFREG | S_IRUGO | S_IWUSR }, 725 { "ac_brightness" , &acpi_pcc_ac_brightness_fops, S_IFREG | S_IRUGO | S_IWUSR },
691 { "dc_brightness_max" , &acpi_pcc_dc_brightness_max_fops,S_IRUGO }, 726 { "dc_brightness_max" , &acpi_pcc_dc_brightness_max_fops,S_IRUGO },
692 { "dc_brightness_min" , &acpi_pcc_dc_brightness_min_fops,S_IRUGO }, 727 { "dc_brightness_min" , &acpi_pcc_dc_brightness_min_fops,S_IRUGO },
693 { "dc_brightness" , &acpi_pcc_dc_brightness_fops, S_IFREG | S_IRUGO | S_IWUSR }, 728 { "dc_brightness" , &acpi_pcc_dc_brightness_fops, S_IFREG | S_IRUGO | S_IWUSR },
694 { "brightness" , &acpi_pcc_brightness_fops, S_IFREG | S_IRUGO | S_IWUSR }, 729 { "brightness" , &acpi_pcc_brightness_fops, S_IFREG | S_IRUGO | S_IWUSR },
695 { "mute", &acpi_pcc_mute_fops, S_IFREG | S_IRUGO | S_IWUSR }, 730 { "mute", &acpi_pcc_mute_fops, S_IFREG | S_IRUGO | S_IWUSR },
696 { NULL, NULL, 0 }, 731 { NULL, NULL, 0 },
697}; 732};
698 733
699ProcItem pcc_proc_items[] = 734ProcItem acpi_pcc_proc_items[] = {
700{
701 { "sticky_key", &acpi_pcc_sticky_key_fops, S_IFREG | S_IRUGO | S_IWUSR }, 735 { "sticky_key", &acpi_pcc_sticky_key_fops, S_IFREG | S_IRUGO | S_IWUSR },
702 { "keyinput", &acpi_pcc_keyinput_fops, S_IFREG | S_IRUGO | S_IWUSR }, 736 { "keyinput", &acpi_pcc_keyinput_fops, S_IFREG | S_IRUGO | S_IWUSR },
703 { "version", &acpi_pcc_version_fops, S_IRUGO }, 737 { "version", &acpi_pcc_version_fops, S_IRUGO },
704 { NULL, NULL, 0 }, 738 { NULL, NULL, 0 },
705}; 739};
706 740
707static int acpi_pcc_add_device(struct acpi_device *device, 741static int __devinit acpi_pcc_add_device(struct acpi_device *device,
708 ProcItem *proc_items, 742 ProcItem *proc_items,
709 int num) 743 int num)
710{ 744{
745 struct acpi_hotkey *hotkey = (struct acpi_hotkey*)acpi_driver_data(device);
711 struct proc_dir_entry* proc; 746 struct proc_dir_entry* proc;
712 ProcItem* item; 747 ProcItem* item;
713 int i; 748 int i;
714 struct acpi_hotkey *hotkey = (struct acpi_hotkey*)acpi_driver_data(device);
715 749
716 for (item = proc_items, i = 0; item->name && i < num; ++item, ++i) { 750 for (item = proc_items, i = 0; item->name && i < num; ++item, ++i) {
717 proc = create_proc_entry(item->name, item->flag, hotkey->proc_dir_entry); 751 proc = create_proc_entry(item->name, item->flag, hotkey->proc_dir_entry);
@@ -724,16 +758,16 @@ static int acpi_pcc_add_device(struct acpi_device *device,
724 item--; 758 item--;
725 remove_proc_entry(item->name, hotkey->proc_dir_entry); 759 remove_proc_entry(item->name, hotkey->proc_dir_entry);
726 } 760 }
727 return -ENODEV; 761 return_VALUE(-ENODEV);
728 } 762 }
729 } 763 }
730 return 0; 764 return_VALUE(0);
731} 765}
732 766
733static int acpi_pcc_proc_init(struct acpi_device *device) 767static int __devinit acpi_pcc_proc_init(struct acpi_device *device)
734{ 768{
735 struct proc_dir_entry* acpi_pcc_dir; 769 struct proc_dir_entry *acpi_pcc_dir;
736 struct acpi_hotkey *hotkey = (struct acpi_hotkey*)acpi_driver_data(device); 770 struct acpi_hotkey *hotkey = (struct acpi_hotkey*)acpi_driver_data(device);
737 acpi_status status; 771 acpi_status status;
738 772
739 ACPI_FUNCTION_TRACE("acpi_pcc_proc_init"); 773 ACPI_FUNCTION_TRACE("acpi_pcc_proc_init");
@@ -748,8 +782,8 @@ static int acpi_pcc_proc_init(struct acpi_device *device)
748 acpi_pcc_dir->owner = THIS_MODULE; 782 acpi_pcc_dir->owner = THIS_MODULE;
749 hotkey->proc_dir_entry = acpi_pcc_dir; 783 hotkey->proc_dir_entry = acpi_pcc_dir;
750 784
751 status = acpi_pcc_add_device(device, pcc_proc_items_sifr, hotkey->num_sifr); 785 status = acpi_pcc_add_device(device, acpi_pcc_proc_items_sifr, hotkey->num_sifr);
752 status |= acpi_pcc_add_device(device, pcc_proc_items, sizeof(pcc_proc_items)/sizeof(ProcItem)); 786 status |= acpi_pcc_add_device(device, acpi_pcc_proc_items, ARRAY_SIZE(acpi_pcc_proc_items));
753 if (unlikely(status)) { 787 if (unlikely(status)) {
754 remove_proc_entry(PROC_PCC, acpi_root_dir); 788 remove_proc_entry(PROC_PCC, acpi_root_dir);
755 hotkey->proc_dir_entry = NULL; 789 hotkey->proc_dir_entry = NULL;
@@ -759,9 +793,9 @@ static int acpi_pcc_proc_init(struct acpi_device *device)
759 return_VALUE(status); 793 return_VALUE(status);
760} 794}
761 795
762static void acpi_pcc_remove_device(struct acpi_device *device, 796static void __devexit acpi_pcc_remove_device(struct acpi_device *device,
763 ProcItem *proc_items, 797 ProcItem *proc_items,
764 int num) 798 int num)
765{ 799{
766 struct acpi_hotkey *hotkey = (struct acpi_hotkey*)acpi_driver_data(device); 800 struct acpi_hotkey *hotkey = (struct acpi_hotkey*)acpi_driver_data(device);
767 ProcItem* item; 801 ProcItem* item;
@@ -771,131 +805,165 @@ static void acpi_pcc_remove_device(struct acpi_device *device,
771 remove_proc_entry(item->name, hotkey->proc_dir_entry); 805 remove_proc_entry(item->name, hotkey->proc_dir_entry);
772 } 806 }
773 807
774 return; 808 return_VOID;
809}
810
811/* *************************************************************************
812 Power Management
813 ************************************************************************* */
814#ifdef CONFIG_PM
815static int acpi_pcc_hotkey_resume(struct acpi_device *device)
816{
817 struct acpi_hotkey *hotkey = acpi_driver_data(device);
818 acpi_status status = AE_OK;
819
820 ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_resume");
821
822 if (device == NULL || hotkey == NULL) { return_VALUE(-EINVAL); }
823
824 if (hotkey->num_sifr != 0) {
825 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Sticky mode restore: %d\n", hotkey->sticky_mode));
826
827 status = acpi_pcc_write_sset(hotkey, SINF_STICKY_KEY, hotkey->sticky_mode);
828 }
829 if (status != AE_OK) { return_VALUE(-EINVAL); }
830
831 return_VALUE(0);
775} 832}
833#endif
776 834
777/* -------------------------------------------------------------------------- 835/* *************************************************************************
778 input init 836 Module init/remove
779 -------------------------------------------------------------------------- */ 837 ************************************************************************* */
780static int acpi_pcc_init_input(struct acpi_hotkey *hotkey) 838/* -------------------------------------------------------------------------
839 input
840 ------------------------------------------------------------------------- */
841static int __devinit acpi_pcc_init_input(struct acpi_hotkey *hotkey)
781{ 842{
782 struct input_dev *hotk_input_dev; 843 struct input_dev *hotk_input_dev;
783 struct pcc_keyinput *pcc_keyinput; 844 struct pcc_keyinput *pcc_keyinput;
845 int error;
784 846
785 ACPI_FUNCTION_TRACE("acpi_pcc_init_input"); 847 ACPI_FUNCTION_TRACE("acpi_pcc_init_input");
786 848
787#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
788 hotk_input_dev = input_allocate_device(); 849 hotk_input_dev = input_allocate_device();
789 if (!hotk_input_dev) {
790 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't allocate input device for hotkey"));
791 return_VALUE(-ENOMEM);
792 }
793#else
794 hotk_input_dev = kcalloc(1, sizeof(struct input_dev),GFP_KERNEL);
795 if (hotk_input_dev == NULL) { 850 if (hotk_input_dev == NULL) {
796 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't allocate mem for hotkey")); 851 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't allocate input device for hotkey"));
797 return_VALUE(-ENOMEM); 852 goto err_input;
798 } 853 }
799#endif
800 854
801 pcc_keyinput = kcalloc(1,sizeof(struct pcc_keyinput),GFP_KERNEL); 855 pcc_keyinput = kcalloc(1, sizeof(struct pcc_keyinput), GFP_KERNEL);
802 856
803 if (pcc_keyinput == NULL) { 857 if (pcc_keyinput == NULL) {
804 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't allocate mem for hotkey")); 858 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't allocate mem for private data"));
805 input_unregister_device(hotk_input_dev); 859 goto err_pcc;
806 return_VALUE(-ENOMEM);
807 } 860 }
808 861
809 hotk_input_dev->evbit[0] = BIT(EV_KEY); 862 hotk_input_dev->evbit[0] = BIT(EV_KEY);
810 863
811 set_bit(KEY_BRIGHTNESSDOWN, hotk_input_dev->keybit); 864 set_bit(KEY_BRIGHTNESSDOWN, hotk_input_dev->keybit);
812 set_bit(KEY_BRIGHTNESSUP, hotk_input_dev->keybit); 865 set_bit(KEY_BRIGHTNESSUP, hotk_input_dev->keybit);
813 set_bit(KEY_MUTE, hotk_input_dev->keybit); 866 set_bit(KEY_MUTE, hotk_input_dev->keybit);
814 set_bit(KEY_VOLUMEDOWN, hotk_input_dev->keybit); 867 set_bit(KEY_VOLUMEDOWN, hotk_input_dev->keybit);
815 set_bit(KEY_VOLUMEUP, hotk_input_dev->keybit); 868 set_bit(KEY_VOLUMEUP, hotk_input_dev->keybit);
816 set_bit(KEY_SLEEP, hotk_input_dev->keybit); 869 set_bit(KEY_SLEEP, hotk_input_dev->keybit);
817 set_bit(KEY_BATT, hotk_input_dev->keybit); 870 set_bit(KEY_BATT, hotk_input_dev->keybit);
818 set_bit(KEY_SUSPEND, hotk_input_dev->keybit); 871 set_bit(KEY_SUSPEND, hotk_input_dev->keybit);
819 872
820 hotk_input_dev->name = ACPI_PCC_DRIVER_NAME; 873 hotk_input_dev->name = ACPI_PCC_DRIVER_NAME;
821 hotk_input_dev->phys = ACPI_PCC_INPUT_PHYS; 874 hotk_input_dev->phys = ACPI_PCC_INPUT_PHYS;
822 hotk_input_dev->id.bustype = 0x1a; /* XXX FIXME: BUS_I8042? */ 875 hotk_input_dev->id.bustype = BUS_PCC_HOTKEY;
823 hotk_input_dev->id.vendor = 0x0001; 876 hotk_input_dev->id.vendor = 0x0001;
824 hotk_input_dev->id.product = 0x0001; 877 hotk_input_dev->id.product = 0x0001;
825 hotk_input_dev->id.version = 0x0100; 878 hotk_input_dev->id.version = 0x0100;
826 879
827 pcc_keyinput->key_mode = 1; /* default on */ 880 pcc_keyinput->key_mode = PCC_KEYINPUT_MODE;
828 pcc_keyinput->hotkey = hotkey; 881 pcc_keyinput->hotkey = hotkey;
829 882
830 input_set_drvdata(hotk_input_dev, pcc_keyinput); 883 input_set_drvdata(hotk_input_dev, pcc_keyinput);
831 884
832 hotkey->input_dev = hotk_input_dev; 885 hotkey->input_dev = hotk_input_dev;
833 886
887 error = input_register_device(hotk_input_dev);
834 888
835 input_register_device(hotk_input_dev); 889 if (error) {
890 goto err_pcc;
891 }
836 892
837 return_VALUE(0); 893 return_VALUE(0);
838}
839 894
840/* -------------------------------------------------------------------------- 895 err_pcc:
841 module init 896 input_unregister_device(hotk_input_dev);
842 -------------------------------------------------------------------------- */ 897 err_input:
898 return_VALUE(-ENOMEM);
899}
843 900
844static int acpi_pcc_hotkey_resume(struct acpi_device *device) 901static void __devexit acpi_pcc_remove_input(struct acpi_hotkey *hotkey)
845{ 902{
846 struct acpi_hotkey *hotkey = acpi_driver_data(device); 903 struct input_dev *hotk_input_dev;
847 acpi_status status = AE_OK; 904 struct pcc_keyinput *pcc_keyinput;
848 905
849 ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_resume"); 906 ACPI_FUNCTION_TRACE("acpi_pcc_remove_input");
850 907
851 if (device == NULL || hotkey == NULL) { return_VALUE(-EINVAL); } 908 if (hotkey == NULL) {
909 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Can't free memory"));
910 return_VOID;
911 }
852 912
853 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Sticky mode restore: %d\n", hotkey->sticky_mode)); 913 hotk_input_dev = hotkey->input_dev;
914 pcc_keyinput = input_get_drvdata(hotk_input_dev);
854 915
855 status = acpi_pcc_write_sset(hotkey, SINF_STICKY_KEY, hotkey->sticky_mode); 916 input_unregister_device(hotk_input_dev);
856 917
857 return_VALUE(status == AE_OK ? 0 : -EINVAL); 918 kfree(pcc_keyinput);
858} 919}
859 920
860static int acpi_pcc_hotkey_add (struct acpi_device *device) 921/* -------------------------------------------------------------------------
922 ACPI
923 ------------------------------------------------------------------------- */
924static int __devinit acpi_pcc_hotkey_add (struct acpi_device *device)
861{ 925{
862 acpi_status status = AE_OK; 926 acpi_status status = AE_OK;
863 struct acpi_hotkey *hotkey = NULL; 927 struct acpi_hotkey *hotkey = NULL;
864 int num_sifr, result; 928 int sifr_status, num_sifr, result;
865 929
866 ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_add"); 930 ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_add");
867 931
868 if (!device) { 932 if (device == NULL) {
869 return_VALUE(-EINVAL); 933 return_VALUE(-EINVAL);
870 } 934 }
871 935
872 num_sifr = acpi_pcc_get_sqty(device); 936 sifr_status = acpi_pcc_get_sqty(device);
873 937
874 if (num_sifr > 255) { 938 if (sifr_status > 255) {
875 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "num_sifr too large")); 939 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "num_sifr too large"));
876 return_VALUE(-ENODEV); 940 return_VALUE(-ENODEV);
877 } 941 }
878 942
879 hotkey = kmalloc(sizeof(struct acpi_hotkey), GFP_KERNEL); 943 if (sifr_status < 0) {
880 if (!hotkey) { 944 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "not support SQTY"));
945 num_sifr = 0;
946 } else {
947 num_sifr = sifr_status;
948 }
949
950 hotkey = kcalloc(1, sizeof(struct acpi_hotkey), GFP_KERNEL);
951 if (hotkey == NULL) {
881 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't allocate mem for hotkey")); 952 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't allocate mem for hotkey"));
882 return_VALUE(-ENOMEM); 953 return_VALUE(-ENOMEM);
883 } 954 }
884 955
885 memset(hotkey, 0, sizeof(struct acpi_hotkey)); 956 hotkey->device = device;
886 957 hotkey->handle = device->handle;
887 hotkey->device = device;
888 hotkey->handle = device->handle;
889 hotkey->num_sifr = num_sifr; 958 hotkey->num_sifr = num_sifr;
890 acpi_driver_data(device) = hotkey; 959 acpi_driver_data(device) = hotkey;
891 strcpy(acpi_device_name(device), ACPI_PCC_DEVICE_NAME); 960 strcpy(acpi_device_name(device), ACPI_PCC_DEVICE_NAME);
892 strcpy(acpi_device_class(device), ACPI_PCC_CLASS); 961 strcpy(acpi_device_class(device), ACPI_PCC_CLASS);
893 962
894 status = acpi_install_notify_handler ( 963 status = acpi_install_notify_handler(hotkey->handle,
895 hotkey->handle, 964 ACPI_DEVICE_NOTIFY,
896 ACPI_DEVICE_NOTIFY, 965 acpi_pcc_hotkey_notify,
897 acpi_pcc_hotkey_notify, 966 hotkey);
898 hotkey);
899 967
900 if (ACPI_FAILURE(status)) { 968 if (ACPI_FAILURE(status)) {
901 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error installing notify handler\n")); 969 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error installing notify handler\n"));
@@ -904,7 +972,7 @@ static int acpi_pcc_hotkey_add (struct acpi_device *device)
904 } 972 }
905 973
906 result = acpi_pcc_init_input(hotkey); 974 result = acpi_pcc_init_input(hotkey);
907 if (result) { 975 if (result != 0) {
908 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error installing keyinput handler\n")); 976 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error installing keyinput handler\n"));
909 kfree(hotkey); 977 kfree(hotkey);
910 return_VALUE(result); 978 return_VALUE(result);
@@ -913,62 +981,72 @@ static int acpi_pcc_hotkey_add (struct acpi_device *device)
913 return_VALUE(acpi_pcc_proc_init(device)); 981 return_VALUE(acpi_pcc_proc_init(device));
914} 982}
915 983
916static int __init acpi_pcc_init(void) 984static int __devexit acpi_pcc_hotkey_remove(struct acpi_device *device, int type)
917{
918 int result = 0;
919
920 ACPI_FUNCTION_TRACE("acpi_pcc_init");
921
922 if (acpi_disabled) {
923 return_VALUE(-ENODEV);
924 }
925
926 result = acpi_bus_register_driver(&acpi_pcc_driver);
927 if (result < 0) {
928 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error registering hotkey driver\n"));
929 return_VALUE(-ENODEV);
930 }
931
932 return_VALUE(0);
933}
934
935module_init(acpi_pcc_init);
936
937static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type)
938{ 985{
939 acpi_status status = AE_OK; 986 acpi_status status = AE_OK;
940 struct acpi_hotkey *hotkey = acpi_driver_data(device); 987 struct acpi_hotkey *hotkey = acpi_driver_data(device);
941 988
942 ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_remove"); 989 ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_remove");
943 990
944 if (!device || !hotkey) 991 if (!device || !hotkey) {
945 return_VALUE(-EINVAL); 992 return_VALUE(-EINVAL);
993 }
946 994
947 if (hotkey->proc_dir_entry) { 995 if (hotkey->proc_dir_entry) {
948 acpi_pcc_remove_device(device, pcc_proc_items_sifr, hotkey->num_sifr); 996 acpi_pcc_remove_device(device, acpi_pcc_proc_items_sifr, hotkey->num_sifr);
949 acpi_pcc_remove_device(device, pcc_proc_items, sizeof(pcc_proc_items)/sizeof(ProcItem)); 997 acpi_pcc_remove_device(device, acpi_pcc_proc_items, ARRAY_SIZE(acpi_pcc_proc_items));
950 remove_proc_entry(PROC_PCC, acpi_root_dir); 998 remove_proc_entry(PROC_PCC, acpi_root_dir);
951 } 999 }
952 1000
953 status = acpi_remove_notify_handler(hotkey->handle, 1001 status = acpi_remove_notify_handler(hotkey->handle,
954 ACPI_DEVICE_NOTIFY, acpi_pcc_hotkey_notify); 1002 ACPI_DEVICE_NOTIFY, acpi_pcc_hotkey_notify);
955 1003
956 if (ACPI_FAILURE(status)) 1004 if (ACPI_FAILURE(status)) {
957 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error removing notify handler\n")); 1005 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error removing notify handler\n"));
1006 }
958 1007
959 input_unregister_device(hotkey->input_dev); 1008 acpi_pcc_remove_input(hotkey);
960 1009 if (hotkey != NULL) {
961 kfree(hotkey); 1010 kfree(hotkey);
1011 }
962 return_VALUE(status == AE_OK); 1012 return_VALUE(status == AE_OK);
963} 1013}
964 1014
1015/* *********************************************************************
1016 Module entry point
1017 ********************************************************************* */
1018static int __init acpi_pcc_init(void)
1019{
1020 int result;
1021
1022 ACPI_FUNCTION_TRACE("acpi_pcc_init");
1023
1024 printk(KERN_INFO LOGPREFIX "loading...\n");
1025
1026 if (acpi_disabled) {
1027 printk(KERN_INFO LOGPREFIX "ACPI disabled.\n");
1028 return_VALUE(-ENODEV);
1029 }
1030
1031 result = acpi_bus_register_driver(&acpi_pcc_driver);
1032 if (result < 0) {
1033 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error registering hotkey driver\n"));
1034 return_VALUE(-ENODEV);
1035 }
1036
1037 return_VALUE(result);
1038}
1039
965static void __exit acpi_pcc_exit(void) 1040static void __exit acpi_pcc_exit(void)
966{ 1041{
967 ACPI_FUNCTION_TRACE("acpi_pcc_exit"); 1042 ACPI_FUNCTION_TRACE("acpi_pcc_exit");
968 1043
1044 printk(KERN_INFO LOGPREFIX "unloading...\n");
1045
969 acpi_bus_unregister_driver(&acpi_pcc_driver); 1046 acpi_bus_unregister_driver(&acpi_pcc_driver);
970 1047
971 return_VOID; 1048 return_VOID;
972} 1049}
973 1050
1051module_init(acpi_pcc_init);
974module_exit(acpi_pcc_exit); 1052module_exit(acpi_pcc_exit);