1 /*
2  *  Copyright (C) 2009  Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 
20 #include <linux/init.h>
21 #include <linux/module.h>
22 #include <linux/slab.h>
23 #include <linux/workqueue.h>
24 #include <acpi/acpi_drivers.h>
25 #include <linux/backlight.h>
26 #include <linux/input.h>
27 #include <linux/rfkill.h>
28 
29 MODULE_LICENSE("GPL");
30 
31 
32 struct cmpc_accel {
33 	int sensitivity;
34 	int g_select;
35 	int inputdev_state;
36 };
37 
38 #define CMPC_ACCEL_DEV_STATE_CLOSED	0
39 #define CMPC_ACCEL_DEV_STATE_OPEN	1
40 
41 #define CMPC_ACCEL_SENSITIVITY_DEFAULT		5
42 #define CMPC_ACCEL_G_SELECT_DEFAULT		0
43 
44 #define CMPC_ACCEL_HID		"ACCE0000"
45 #define CMPC_ACCEL_HID_V4	"ACCE0001"
46 #define CMPC_TABLET_HID		"TBLT0000"
47 #define CMPC_IPML_HID	"IPML200"
48 #define CMPC_KEYS_HID		"FNBT0000"
49 
50 /*
51  * Generic input device code.
52  */
53 
54 typedef void (*input_device_init)(struct input_dev *dev);
55 
56 static int cmpc_add_acpi_notify_device(struct acpi_device *acpi, char *name,
57 				       input_device_init idev_init)
58 {
59 	struct input_dev *inputdev;
60 	int error;
61 
62 	inputdev = input_allocate_device();
63 	if (!inputdev)
64 		return -ENOMEM;
65 	inputdev->name = name;
66 	inputdev->dev.parent = &acpi->dev;
67 	idev_init(inputdev);
68 	error = input_register_device(inputdev);
69 	if (error) {
70 		input_free_device(inputdev);
71 		return error;
72 	}
73 	dev_set_drvdata(&acpi->dev, inputdev);
74 	return 0;
75 }
76 
77 static int cmpc_remove_acpi_notify_device(struct acpi_device *acpi)
78 {
79 	struct input_dev *inputdev = dev_get_drvdata(&acpi->dev);
80 	input_unregister_device(inputdev);
81 	return 0;
82 }
83 
84 /*
85  * Accelerometer code for Classmate V4
86  */
87 static acpi_status cmpc_start_accel_v4(acpi_handle handle)
88 {
89 	union acpi_object param[4];
90 	struct acpi_object_list input;
91 	acpi_status status;
92 
93 	param[0].type = ACPI_TYPE_INTEGER;
94 	param[0].integer.value = 0x3;
95 	param[1].type = ACPI_TYPE_INTEGER;
96 	param[1].integer.value = 0;
97 	param[2].type = ACPI_TYPE_INTEGER;
98 	param[2].integer.value = 0;
99 	param[3].type = ACPI_TYPE_INTEGER;
100 	param[3].integer.value = 0;
101 	input.count = 4;
102 	input.pointer = param;
103 	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
104 	return status;
105 }
106 
107 static acpi_status cmpc_stop_accel_v4(acpi_handle handle)
108 {
109 	union acpi_object param[4];
110 	struct acpi_object_list input;
111 	acpi_status status;
112 
113 	param[0].type = ACPI_TYPE_INTEGER;
114 	param[0].integer.value = 0x4;
115 	param[1].type = ACPI_TYPE_INTEGER;
116 	param[1].integer.value = 0;
117 	param[2].type = ACPI_TYPE_INTEGER;
118 	param[2].integer.value = 0;
119 	param[3].type = ACPI_TYPE_INTEGER;
120 	param[3].integer.value = 0;
121 	input.count = 4;
122 	input.pointer = param;
123 	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
124 	return status;
125 }
126 
127 static acpi_status cmpc_accel_set_sensitivity_v4(acpi_handle handle, int val)
128 {
129 	union acpi_object param[4];
130 	struct acpi_object_list input;
131 
132 	param[0].type = ACPI_TYPE_INTEGER;
133 	param[0].integer.value = 0x02;
134 	param[1].type = ACPI_TYPE_INTEGER;
135 	param[1].integer.value = val;
136 	param[2].type = ACPI_TYPE_INTEGER;
137 	param[2].integer.value = 0;
138 	param[3].type = ACPI_TYPE_INTEGER;
139 	param[3].integer.value = 0;
140 	input.count = 4;
141 	input.pointer = param;
142 	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
143 }
144 
145 static acpi_status cmpc_accel_set_g_select_v4(acpi_handle handle, int val)
146 {
147 	union acpi_object param[4];
148 	struct acpi_object_list input;
149 
150 	param[0].type = ACPI_TYPE_INTEGER;
151 	param[0].integer.value = 0x05;
152 	param[1].type = ACPI_TYPE_INTEGER;
153 	param[1].integer.value = val;
154 	param[2].type = ACPI_TYPE_INTEGER;
155 	param[2].integer.value = 0;
156 	param[3].type = ACPI_TYPE_INTEGER;
157 	param[3].integer.value = 0;
158 	input.count = 4;
159 	input.pointer = param;
160 	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
161 }
162 
163 static acpi_status cmpc_get_accel_v4(acpi_handle handle,
164 				     int16_t *x,
165 				     int16_t *y,
166 				     int16_t *z)
167 {
168 	union acpi_object param[4];
169 	struct acpi_object_list input;
170 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
171 	int16_t *locs;
172 	acpi_status status;
173 
174 	param[0].type = ACPI_TYPE_INTEGER;
175 	param[0].integer.value = 0x01;
176 	param[1].type = ACPI_TYPE_INTEGER;
177 	param[1].integer.value = 0;
178 	param[2].type = ACPI_TYPE_INTEGER;
179 	param[2].integer.value = 0;
180 	param[3].type = ACPI_TYPE_INTEGER;
181 	param[3].integer.value = 0;
182 	input.count = 4;
183 	input.pointer = param;
184 	status = acpi_evaluate_object(handle, "ACMD", &input, &output);
185 	if (ACPI_SUCCESS(status)) {
186 		union acpi_object *obj;
187 		obj = output.pointer;
188 		locs = (int16_t *) obj->buffer.pointer;
189 		*x = locs[0];
190 		*y = locs[1];
191 		*z = locs[2];
192 		kfree(output.pointer);
193 	}
194 	return status;
195 }
196 
197 static void cmpc_accel_handler_v4(struct acpi_device *dev, u32 event)
198 {
199 	if (event == 0x81) {
200 		int16_t x, y, z;
201 		acpi_status status;
202 
203 		status = cmpc_get_accel_v4(dev->handle, &x, &y, &z);
204 		if (ACPI_SUCCESS(status)) {
205 			struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
206 
207 			input_report_abs(inputdev, ABS_X, x);
208 			input_report_abs(inputdev, ABS_Y, y);
209 			input_report_abs(inputdev, ABS_Z, z);
210 			input_sync(inputdev);
211 		}
212 	}
213 }
214 
215 static ssize_t cmpc_accel_sensitivity_show_v4(struct device *dev,
216 					      struct device_attribute *attr,
217 					      char *buf)
218 {
219 	struct acpi_device *acpi;
220 	struct input_dev *inputdev;
221 	struct cmpc_accel *accel;
222 
223 	acpi = to_acpi_device(dev);
224 	inputdev = dev_get_drvdata(&acpi->dev);
225 	accel = dev_get_drvdata(&inputdev->dev);
226 
227 	return sprintf(buf, "%d\n", accel->sensitivity);
228 }
229 
230 static ssize_t cmpc_accel_sensitivity_store_v4(struct device *dev,
231 					       struct device_attribute *attr,
232 					       const char *buf, size_t count)
233 {
234 	struct acpi_device *acpi;
235 	struct input_dev *inputdev;
236 	struct cmpc_accel *accel;
237 	unsigned long sensitivity;
238 	int r;
239 
240 	acpi = to_acpi_device(dev);
241 	inputdev = dev_get_drvdata(&acpi->dev);
242 	accel = dev_get_drvdata(&inputdev->dev);
243 
244 	r = kstrtoul(buf, 0, &sensitivity);
245 	if (r)
246 		return r;
247 
248 	/* sensitivity must be between 1 and 127 */
249 	if (sensitivity < 1 || sensitivity > 127)
250 		return -EINVAL;
251 
252 	accel->sensitivity = sensitivity;
253 	cmpc_accel_set_sensitivity_v4(acpi->handle, sensitivity);
254 
255 	return strnlen(buf, count);
256 }
257 
258 static struct device_attribute cmpc_accel_sensitivity_attr_v4 = {
259 	.attr = { .name = "sensitivity", .mode = 0660 },
260 	.show = cmpc_accel_sensitivity_show_v4,
261 	.store = cmpc_accel_sensitivity_store_v4
262 };
263 
264 static ssize_t cmpc_accel_g_select_show_v4(struct device *dev,
265 					   struct device_attribute *attr,
266 					   char *buf)
267 {
268 	struct acpi_device *acpi;
269 	struct input_dev *inputdev;
270 	struct cmpc_accel *accel;
271 
272 	acpi = to_acpi_device(dev);
273 	inputdev = dev_get_drvdata(&acpi->dev);
274 	accel = dev_get_drvdata(&inputdev->dev);
275 
276 	return sprintf(buf, "%d\n", accel->g_select);
277 }
278 
279 static ssize_t cmpc_accel_g_select_store_v4(struct device *dev,
280 					    struct device_attribute *attr,
281 					    const char *buf, size_t count)
282 {
283 	struct acpi_device *acpi;
284 	struct input_dev *inputdev;
285 	struct cmpc_accel *accel;
286 	unsigned long g_select;
287 	int r;
288 
289 	acpi = to_acpi_device(dev);
290 	inputdev = dev_get_drvdata(&acpi->dev);
291 	accel = dev_get_drvdata(&inputdev->dev);
292 
293 	r = kstrtoul(buf, 0, &g_select);
294 	if (r)
295 		return r;
296 
297 	/* 0 means 1.5g, 1 means 6g, everything else is wrong */
298 	if (g_select != 0 && g_select != 1)
299 		return -EINVAL;
300 
301 	accel->g_select = g_select;
302 	cmpc_accel_set_g_select_v4(acpi->handle, g_select);
303 
304 	return strnlen(buf, count);
305 }
306 
307 static struct device_attribute cmpc_accel_g_select_attr_v4 = {
308 	.attr = { .name = "g_select", .mode = 0660 },
309 	.show = cmpc_accel_g_select_show_v4,
310 	.store = cmpc_accel_g_select_store_v4
311 };
312 
313 static int cmpc_accel_open_v4(struct input_dev *input)
314 {
315 	struct acpi_device *acpi;
316 	struct cmpc_accel *accel;
317 
318 	acpi = to_acpi_device(input->dev.parent);
319 	accel = dev_get_drvdata(&input->dev);
320 
321 	cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
322 	cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
323 
324 	if (ACPI_SUCCESS(cmpc_start_accel_v4(acpi->handle))) {
325 		accel->inputdev_state = CMPC_ACCEL_DEV_STATE_OPEN;
326 		return 0;
327 	}
328 	return -EIO;
329 }
330 
331 static void cmpc_accel_close_v4(struct input_dev *input)
332 {
333 	struct acpi_device *acpi;
334 	struct cmpc_accel *accel;
335 
336 	acpi = to_acpi_device(input->dev.parent);
337 	accel = dev_get_drvdata(&input->dev);
338 
339 	cmpc_stop_accel_v4(acpi->handle);
340 	accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
341 }
342 
343 static void cmpc_accel_idev_init_v4(struct input_dev *inputdev)
344 {
345 	set_bit(EV_ABS, inputdev->evbit);
346 	input_set_abs_params(inputdev, ABS_X, -255, 255, 16, 0);
347 	input_set_abs_params(inputdev, ABS_Y, -255, 255, 16, 0);
348 	input_set_abs_params(inputdev, ABS_Z, -255, 255, 16, 0);
349 	inputdev->open = cmpc_accel_open_v4;
350 	inputdev->close = cmpc_accel_close_v4;
351 }
352 
353 #ifdef CONFIG_PM_SLEEP
354 static int cmpc_accel_suspend_v4(struct device *dev)
355 {
356 	struct input_dev *inputdev;
357 	struct cmpc_accel *accel;
358 
359 	inputdev = dev_get_drvdata(dev);
360 	accel = dev_get_drvdata(&inputdev->dev);
361 
362 	if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN)
363 		return cmpc_stop_accel_v4(to_acpi_device(dev)->handle);
364 
365 	return 0;
366 }
367 
368 static int cmpc_accel_resume_v4(struct device *dev)
369 {
370 	struct input_dev *inputdev;
371 	struct cmpc_accel *accel;
372 
373 	inputdev = dev_get_drvdata(dev);
374 	accel = dev_get_drvdata(&inputdev->dev);
375 
376 	if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN) {
377 		cmpc_accel_set_sensitivity_v4(to_acpi_device(dev)->handle,
378 					      accel->sensitivity);
379 		cmpc_accel_set_g_select_v4(to_acpi_device(dev)->handle,
380 					   accel->g_select);
381 
382 		if (ACPI_FAILURE(cmpc_start_accel_v4(to_acpi_device(dev)->handle)))
383 			return -EIO;
384 	}
385 
386 	return 0;
387 }
388 #endif
389 
390 static int cmpc_accel_add_v4(struct acpi_device *acpi)
391 {
392 	int error;
393 	struct input_dev *inputdev;
394 	struct cmpc_accel *accel;
395 
396 	accel = kmalloc(sizeof(*accel), GFP_KERNEL);
397 	if (!accel)
398 		return -ENOMEM;
399 
400 	accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
401 
402 	accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
403 	cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
404 
405 	error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
406 	if (error)
407 		goto failed_sensitivity;
408 
409 	accel->g_select = CMPC_ACCEL_G_SELECT_DEFAULT;
410 	cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
411 
412 	error = device_create_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
413 	if (error)
414 		goto failed_g_select;
415 
416 	error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel_v4",
417 					    cmpc_accel_idev_init_v4);
418 	if (error)
419 		goto failed_input;
420 
421 	inputdev = dev_get_drvdata(&acpi->dev);
422 	dev_set_drvdata(&inputdev->dev, accel);
423 
424 	return 0;
425 
426 failed_input:
427 	device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
428 failed_g_select:
429 	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
430 failed_sensitivity:
431 	kfree(accel);
432 	return error;
433 }
434 
435 static int cmpc_accel_remove_v4(struct acpi_device *acpi, int type)
436 {
437 	struct input_dev *inputdev;
438 	struct cmpc_accel *accel;
439 
440 	inputdev = dev_get_drvdata(&acpi->dev);
441 	accel = dev_get_drvdata(&inputdev->dev);
442 
443 	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
444 	device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
445 	return cmpc_remove_acpi_notify_device(acpi);
446 }
447 
448 static SIMPLE_DEV_PM_OPS(cmpc_accel_pm, cmpc_accel_suspend_v4,
449 			 cmpc_accel_resume_v4);
450 
451 static const struct acpi_device_id cmpc_accel_device_ids_v4[] = {
452 	{CMPC_ACCEL_HID_V4, 0},
453 	{"", 0}
454 };
455 
456 static struct acpi_driver cmpc_accel_acpi_driver_v4 = {
457 	.owner = THIS_MODULE,
458 	.name = "cmpc_accel_v4",
459 	.class = "cmpc_accel_v4",
460 	.ids = cmpc_accel_device_ids_v4,
461 	.ops = {
462 		.add = cmpc_accel_add_v4,
463 		.remove = cmpc_accel_remove_v4,
464 		.notify = cmpc_accel_handler_v4,
465 	},
466 	.drv.pm = &cmpc_accel_pm,
467 };
468 
469 
470 /*
471  * Accelerometer code for Classmate versions prior to V4
472  */
473 static acpi_status cmpc_start_accel(acpi_handle handle)
474 {
475 	union acpi_object param[2];
476 	struct acpi_object_list input;
477 	acpi_status status;
478 
479 	param[0].type = ACPI_TYPE_INTEGER;
480 	param[0].integer.value = 0x3;
481 	param[1].type = ACPI_TYPE_INTEGER;
482 	input.count = 2;
483 	input.pointer = param;
484 	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
485 	return status;
486 }
487 
488 static acpi_status cmpc_stop_accel(acpi_handle handle)
489 {
490 	union acpi_object param[2];
491 	struct acpi_object_list input;
492 	acpi_status status;
493 
494 	param[0].type = ACPI_TYPE_INTEGER;
495 	param[0].integer.value = 0x4;
496 	param[1].type = ACPI_TYPE_INTEGER;
497 	input.count = 2;
498 	input.pointer = param;
499 	status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
500 	return status;
501 }
502 
503 static acpi_status cmpc_accel_set_sensitivity(acpi_handle handle, int val)
504 {
505 	union acpi_object param[2];
506 	struct acpi_object_list input;
507 
508 	param[0].type = ACPI_TYPE_INTEGER;
509 	param[0].integer.value = 0x02;
510 	param[1].type = ACPI_TYPE_INTEGER;
511 	param[1].integer.value = val;
512 	input.count = 2;
513 	input.pointer = param;
514 	return acpi_evaluate_object(handle, "ACMD", &input, NULL);
515 }
516 
517 static acpi_status cmpc_get_accel(acpi_handle handle,
518 				  unsigned char *x,
519 				  unsigned char *y,
520 				  unsigned char *z)
521 {
522 	union acpi_object param[2];
523 	struct acpi_object_list input;
524 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, 0 };
525 	unsigned char *locs;
526 	acpi_status status;
527 
528 	param[0].type = ACPI_TYPE_INTEGER;
529 	param[0].integer.value = 0x01;
530 	param[1].type = ACPI_TYPE_INTEGER;
531 	input.count = 2;
532 	input.pointer = param;
533 	status = acpi_evaluate_object(handle, "ACMD", &input, &output);
534 	if (ACPI_SUCCESS(status)) {
535 		union acpi_object *obj;
536 		obj = output.pointer;
537 		locs = obj->buffer.pointer;
538 		*x = locs[0];
539 		*y = locs[1];
540 		*z = locs[2];
541 		kfree(output.pointer);
542 	}
543 	return status;
544 }
545 
546 static void cmpc_accel_handler(struct acpi_device *dev, u32 event)
547 {
548 	if (event == 0x81) {
549 		unsigned char x, y, z;
550 		acpi_status status;
551 
552 		status = cmpc_get_accel(dev->handle, &x, &y, &z);
553 		if (ACPI_SUCCESS(status)) {
554 			struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
555 
556 			input_report_abs(inputdev, ABS_X, x);
557 			input_report_abs(inputdev, ABS_Y, y);
558 			input_report_abs(inputdev, ABS_Z, z);
559 			input_sync(inputdev);
560 		}
561 	}
562 }
563 
564 static ssize_t cmpc_accel_sensitivity_show(struct device *dev,
565 					   struct device_attribute *attr,
566 					   char *buf)
567 {
568 	struct acpi_device *acpi;
569 	struct input_dev *inputdev;
570 	struct cmpc_accel *accel;
571 
572 	acpi = to_acpi_device(dev);
573 	inputdev = dev_get_drvdata(&acpi->dev);
574 	accel = dev_get_drvdata(&inputdev->dev);
575 
576 	return sprintf(buf, "%d\n", accel->sensitivity);
577 }
578 
579 static ssize_t cmpc_accel_sensitivity_store(struct device *dev,
580 					    struct device_attribute *attr,
581 					    const char *buf, size_t count)
582 {
583 	struct acpi_device *acpi;
584 	struct input_dev *inputdev;
585 	struct cmpc_accel *accel;
586 	unsigned long sensitivity;
587 	int r;
588 
589 	acpi = to_acpi_device(dev);
590 	inputdev = dev_get_drvdata(&acpi->dev);
591 	accel = dev_get_drvdata(&inputdev->dev);
592 
593 	r = strict_strtoul(buf, 0, &sensitivity);
594 	if (r)
595 		return r;
596 
597 	accel->sensitivity = sensitivity;
598 	cmpc_accel_set_sensitivity(acpi->handle, sensitivity);
599 
600 	return strnlen(buf, count);
601 }
602 
603 static struct device_attribute cmpc_accel_sensitivity_attr = {
604 	.attr = { .name = "sensitivity", .mode = 0660 },
605 	.show = cmpc_accel_sensitivity_show,
606 	.store = cmpc_accel_sensitivity_store
607 };
608 
609 static int cmpc_accel_open(struct input_dev *input)
610 {
611 	struct acpi_device *acpi;
612 
613 	acpi = to_acpi_device(input->dev.parent);
614 	if (ACPI_SUCCESS(cmpc_start_accel(acpi->handle)))
615 		return 0;
616 	return -EIO;
617 }
618 
619 static void cmpc_accel_close(struct input_dev *input)
620 {
621 	struct acpi_device *acpi;
622 
623 	acpi = to_acpi_device(input->dev.parent);
624 	cmpc_stop_accel(acpi->handle);
625 }
626 
627 static void cmpc_accel_idev_init(struct input_dev *inputdev)
628 {
629 	set_bit(EV_ABS, inputdev->evbit);
630 	input_set_abs_params(inputdev, ABS_X, 0, 255, 8, 0);
631 	input_set_abs_params(inputdev, ABS_Y, 0, 255, 8, 0);
632 	input_set_abs_params(inputdev, ABS_Z, 0, 255, 8, 0);
633 	inputdev->open = cmpc_accel_open;
634 	inputdev->close = cmpc_accel_close;
635 }
636 
637 static int cmpc_accel_add(struct acpi_device *acpi)
638 {
639 	int error;
640 	struct input_dev *inputdev;
641 	struct cmpc_accel *accel;
642 
643 	accel = kmalloc(sizeof(*accel), GFP_KERNEL);
644 	if (!accel)
645 		return -ENOMEM;
646 
647 	accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
648 	cmpc_accel_set_sensitivity(acpi->handle, accel->sensitivity);
649 
650 	error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
651 	if (error)
652 		goto failed_file;
653 
654 	error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel",
655 					    cmpc_accel_idev_init);
656 	if (error)
657 		goto failed_input;
658 
659 	inputdev = dev_get_drvdata(&acpi->dev);
660 	dev_set_drvdata(&inputdev->dev, accel);
661 
662 	return 0;
663 
664 failed_input:
665 	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
666 failed_file:
667 	kfree(accel);
668 	return error;
669 }
670 
671 static int cmpc_accel_remove(struct acpi_device *acpi, int type)
672 {
673 	struct input_dev *inputdev;
674 	struct cmpc_accel *accel;
675 
676 	inputdev = dev_get_drvdata(&acpi->dev);
677 	accel = dev_get_drvdata(&inputdev->dev);
678 
679 	device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
680 	return cmpc_remove_acpi_notify_device(acpi);
681 }
682 
683 static const struct acpi_device_id cmpc_accel_device_ids[] = {
684 	{CMPC_ACCEL_HID, 0},
685 	{"", 0}
686 };
687 
688 static struct acpi_driver cmpc_accel_acpi_driver = {
689 	.owner = THIS_MODULE,
690 	.name = "cmpc_accel",
691 	.class = "cmpc_accel",
692 	.ids = cmpc_accel_device_ids,
693 	.ops = {
694 		.add = cmpc_accel_add,
695 		.remove = cmpc_accel_remove,
696 		.notify = cmpc_accel_handler,
697 	}
698 };
699 
700 
701 /*
702  * Tablet mode code.
703  */
704 static acpi_status cmpc_get_tablet(acpi_handle handle,
705 				   unsigned long long *value)
706 {
707 	union acpi_object param;
708 	struct acpi_object_list input;
709 	unsigned long long output;
710 	acpi_status status;
711 
712 	param.type = ACPI_TYPE_INTEGER;
713 	param.integer.value = 0x01;
714 	input.count = 1;
715 	input.pointer = &param;
716 	status = acpi_evaluate_integer(handle, "TCMD", &input, &output);
717 	if (ACPI_SUCCESS(status))
718 		*value = output;
719 	return status;
720 }
721 
722 static void cmpc_tablet_handler(struct acpi_device *dev, u32 event)
723 {
724 	unsigned long long val = 0;
725 	struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
726 
727 	if (event == 0x81) {
728 		if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) {
729 			input_report_switch(inputdev, SW_TABLET_MODE, !val);
730 			input_sync(inputdev);
731 		}
732 	}
733 }
734 
735 static void cmpc_tablet_idev_init(struct input_dev *inputdev)
736 {
737 	unsigned long long val = 0;
738 	struct acpi_device *acpi;
739 
740 	set_bit(EV_SW, inputdev->evbit);
741 	set_bit(SW_TABLET_MODE, inputdev->swbit);
742 
743 	acpi = to_acpi_device(inputdev->dev.parent);
744 	if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) {
745 		input_report_switch(inputdev, SW_TABLET_MODE, !val);
746 		input_sync(inputdev);
747 	}
748 }
749 
750 static int cmpc_tablet_add(struct acpi_device *acpi)
751 {
752 	return cmpc_add_acpi_notify_device(acpi, "cmpc_tablet",
753 					   cmpc_tablet_idev_init);
754 }
755 
756 static int cmpc_tablet_remove(struct acpi_device *acpi, int type)
757 {
758 	return cmpc_remove_acpi_notify_device(acpi);
759 }
760 
761 #ifdef CONFIG_PM_SLEEP
762 static int cmpc_tablet_resume(struct device *dev)
763 {
764 	struct input_dev *inputdev = dev_get_drvdata(dev);
765 
766 	unsigned long long val = 0;
767 	if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) {
768 		input_report_switch(inputdev, SW_TABLET_MODE, !val);
769 		input_sync(inputdev);
770 	}
771 	return 0;
772 }
773 #endif
774 
775 static SIMPLE_DEV_PM_OPS(cmpc_tablet_pm, NULL, cmpc_tablet_resume);
776 
777 static const struct acpi_device_id cmpc_tablet_device_ids[] = {
778 	{CMPC_TABLET_HID, 0},
779 	{"", 0}
780 };
781 
782 static struct acpi_driver cmpc_tablet_acpi_driver = {
783 	.owner = THIS_MODULE,
784 	.name = "cmpc_tablet",
785 	.class = "cmpc_tablet",
786 	.ids = cmpc_tablet_device_ids,
787 	.ops = {
788 		.add = cmpc_tablet_add,
789 		.remove = cmpc_tablet_remove,
790 		.notify = cmpc_tablet_handler,
791 	},
792 	.drv.pm = &cmpc_tablet_pm,
793 };
794 
795 
796 /*
797  * Backlight code.
798  */
799 
800 static acpi_status cmpc_get_brightness(acpi_handle handle,
801 				       unsigned long long *value)
802 {
803 	union acpi_object param;
804 	struct acpi_object_list input;
805 	unsigned long long output;
806 	acpi_status status;
807 
808 	param.type = ACPI_TYPE_INTEGER;
809 	param.integer.value = 0xC0;
810 	input.count = 1;
811 	input.pointer = &param;
812 	status = acpi_evaluate_integer(handle, "GRDI", &input, &output);
813 	if (ACPI_SUCCESS(status))
814 		*value = output;
815 	return status;
816 }
817 
818 static acpi_status cmpc_set_brightness(acpi_handle handle,
819 				       unsigned long long value)
820 {
821 	union acpi_object param[2];
822 	struct acpi_object_list input;
823 	acpi_status status;
824 	unsigned long long output;
825 
826 	param[0].type = ACPI_TYPE_INTEGER;
827 	param[0].integer.value = 0xC0;
828 	param[1].type = ACPI_TYPE_INTEGER;
829 	param[1].integer.value = value;
830 	input.count = 2;
831 	input.pointer = param;
832 	status = acpi_evaluate_integer(handle, "GWRI", &input, &output);
833 	return status;
834 }
835 
836 static int cmpc_bl_get_brightness(struct backlight_device *bd)
837 {
838 	acpi_status status;
839 	acpi_handle handle;
840 	unsigned long long brightness;
841 
842 	handle = bl_get_data(bd);
843 	status = cmpc_get_brightness(handle, &brightness);
844 	if (ACPI_SUCCESS(status))
845 		return brightness;
846 	else
847 		return -1;
848 }
849 
850 static int cmpc_bl_update_status(struct backlight_device *bd)
851 {
852 	acpi_status status;
853 	acpi_handle handle;
854 
855 	handle = bl_get_data(bd);
856 	status = cmpc_set_brightness(handle, bd->props.brightness);
857 	if (ACPI_SUCCESS(status))
858 		return 0;
859 	else
860 		return -1;
861 }
862 
863 static const struct backlight_ops cmpc_bl_ops = {
864 	.get_brightness = cmpc_bl_get_brightness,
865 	.update_status = cmpc_bl_update_status
866 };
867 
868 /*
869  * RFKILL code.
870  */
871 
872 static acpi_status cmpc_get_rfkill_wlan(acpi_handle handle,
873 					unsigned long long *value)
874 {
875 	union acpi_object param;
876 	struct acpi_object_list input;
877 	unsigned long long output;
878 	acpi_status status;
879 
880 	param.type = ACPI_TYPE_INTEGER;
881 	param.integer.value = 0xC1;
882 	input.count = 1;
883 	input.pointer = &param;
884 	status = acpi_evaluate_integer(handle, "GRDI", &input, &output);
885 	if (ACPI_SUCCESS(status))
886 		*value = output;
887 	return status;
888 }
889 
890 static acpi_status cmpc_set_rfkill_wlan(acpi_handle handle,
891 					unsigned long long value)
892 {
893 	union acpi_object param[2];
894 	struct acpi_object_list input;
895 	acpi_status status;
896 	unsigned long long output;
897 
898 	param[0].type = ACPI_TYPE_INTEGER;
899 	param[0].integer.value = 0xC1;
900 	param[1].type = ACPI_TYPE_INTEGER;
901 	param[1].integer.value = value;
902 	input.count = 2;
903 	input.pointer = param;
904 	status = acpi_evaluate_integer(handle, "GWRI", &input, &output);
905 	return status;
906 }
907 
908 static void cmpc_rfkill_query(struct rfkill *rfkill, void *data)
909 {
910 	acpi_status status;
911 	acpi_handle handle;
912 	unsigned long long state;
913 	bool blocked;
914 
915 	handle = data;
916 	status = cmpc_get_rfkill_wlan(handle, &state);
917 	if (ACPI_SUCCESS(status)) {
918 		blocked = state & 1 ? false : true;
919 		rfkill_set_sw_state(rfkill, blocked);
920 	}
921 }
922 
923 static int cmpc_rfkill_block(void *data, bool blocked)
924 {
925 	acpi_status status;
926 	acpi_handle handle;
927 	unsigned long long state;
928 	bool is_blocked;
929 
930 	handle = data;
931 	status = cmpc_get_rfkill_wlan(handle, &state);
932 	if (ACPI_FAILURE(status))
933 		return -ENODEV;
934 	/* Check if we really need to call cmpc_set_rfkill_wlan */
935 	is_blocked = state & 1 ? false : true;
936 	if (is_blocked != blocked) {
937 		state = blocked ? 0 : 1;
938 		status = cmpc_set_rfkill_wlan(handle, state);
939 		if (ACPI_FAILURE(status))
940 			return -ENODEV;
941 	}
942 	return 0;
943 }
944 
945 static const struct rfkill_ops cmpc_rfkill_ops = {
946 	.query = cmpc_rfkill_query,
947 	.set_block = cmpc_rfkill_block,
948 };
949 
950 /*
951  * Common backlight and rfkill code.
952  */
953 
954 struct ipml200_dev {
955 	struct backlight_device *bd;
956 	struct rfkill *rf;
957 };
958 
959 static int cmpc_ipml_add(struct acpi_device *acpi)
960 {
961 	int retval;
962 	struct ipml200_dev *ipml;
963 	struct backlight_properties props;
964 
965 	ipml = kmalloc(sizeof(*ipml), GFP_KERNEL);
966 	if (ipml == NULL)
967 		return -ENOMEM;
968 
969 	memset(&props, 0, sizeof(struct backlight_properties));
970 	props.type = BACKLIGHT_PLATFORM;
971 	props.max_brightness = 7;
972 	ipml->bd = backlight_device_register("cmpc_bl", &acpi->dev,
973 					     acpi->handle, &cmpc_bl_ops,
974 					     &props);
975 	if (IS_ERR(ipml->bd)) {
976 		retval = PTR_ERR(ipml->bd);
977 		goto out_bd;
978 	}
979 
980 	ipml->rf = rfkill_alloc("cmpc_rfkill", &acpi->dev, RFKILL_TYPE_WLAN,
981 				&cmpc_rfkill_ops, acpi->handle);
982 	/*
983 	 * If RFKILL is disabled, rfkill_alloc will return ERR_PTR(-ENODEV).
984 	 * This is OK, however, since all other uses of the device will not
985 	 * derefence it.
986 	 */
987 	if (ipml->rf) {
988 		retval = rfkill_register(ipml->rf);
989 		if (retval) {
990 			rfkill_destroy(ipml->rf);
991 			ipml->rf = NULL;
992 		}
993 	}
994 
995 	dev_set_drvdata(&acpi->dev, ipml);
996 	return 0;
997 
998 out_bd:
999 	kfree(ipml);
1000 	return retval;
1001 }
1002 
1003 static int cmpc_ipml_remove(struct acpi_device *acpi, int type)
1004 {
1005 	struct ipml200_dev *ipml;
1006 
1007 	ipml = dev_get_drvdata(&acpi->dev);
1008 
1009 	backlight_device_unregister(ipml->bd);
1010 
1011 	if (ipml->rf) {
1012 		rfkill_unregister(ipml->rf);
1013 		rfkill_destroy(ipml->rf);
1014 	}
1015 
1016 	kfree(ipml);
1017 
1018 	return 0;
1019 }
1020 
1021 static const struct acpi_device_id cmpc_ipml_device_ids[] = {
1022 	{CMPC_IPML_HID, 0},
1023 	{"", 0}
1024 };
1025 
1026 static struct acpi_driver cmpc_ipml_acpi_driver = {
1027 	.owner = THIS_MODULE,
1028 	.name = "cmpc",
1029 	.class = "cmpc",
1030 	.ids = cmpc_ipml_device_ids,
1031 	.ops = {
1032 		.add = cmpc_ipml_add,
1033 		.remove = cmpc_ipml_remove
1034 	}
1035 };
1036 
1037 
1038 /*
1039  * Extra keys code.
1040  */
1041 static int cmpc_keys_codes[] = {
1042 	KEY_UNKNOWN,
1043 	KEY_WLAN,
1044 	KEY_SWITCHVIDEOMODE,
1045 	KEY_BRIGHTNESSDOWN,
1046 	KEY_BRIGHTNESSUP,
1047 	KEY_VENDOR,
1048 	KEY_UNKNOWN,
1049 	KEY_CAMERA,
1050 	KEY_BACK,
1051 	KEY_FORWARD,
1052 	KEY_MAX
1053 };
1054 
1055 static void cmpc_keys_handler(struct acpi_device *dev, u32 event)
1056 {
1057 	struct input_dev *inputdev;
1058 	int code = KEY_MAX;
1059 
1060 	if ((event & 0x0F) < ARRAY_SIZE(cmpc_keys_codes))
1061 		code = cmpc_keys_codes[event & 0x0F];
1062 	inputdev = dev_get_drvdata(&dev->dev);
1063 	input_report_key(inputdev, code, !(event & 0x10));
1064 	input_sync(inputdev);
1065 }
1066 
1067 static void cmpc_keys_idev_init(struct input_dev *inputdev)
1068 {
1069 	int i;
1070 
1071 	set_bit(EV_KEY, inputdev->evbit);
1072 	for (i = 0; cmpc_keys_codes[i] != KEY_MAX; i++)
1073 		set_bit(cmpc_keys_codes[i], inputdev->keybit);
1074 }
1075 
1076 static int cmpc_keys_add(struct acpi_device *acpi)
1077 {
1078 	return cmpc_add_acpi_notify_device(acpi, "cmpc_keys",
1079 					   cmpc_keys_idev_init);
1080 }
1081 
1082 static int cmpc_keys_remove(struct acpi_device *acpi, int type)
1083 {
1084 	return cmpc_remove_acpi_notify_device(acpi);
1085 }
1086 
1087 static const struct acpi_device_id cmpc_keys_device_ids[] = {
1088 	{CMPC_KEYS_HID, 0},
1089 	{"", 0}
1090 };
1091 
1092 static struct acpi_driver cmpc_keys_acpi_driver = {
1093 	.owner = THIS_MODULE,
1094 	.name = "cmpc_keys",
1095 	.class = "cmpc_keys",
1096 	.ids = cmpc_keys_device_ids,
1097 	.ops = {
1098 		.add = cmpc_keys_add,
1099 		.remove = cmpc_keys_remove,
1100 		.notify = cmpc_keys_handler,
1101 	}
1102 };
1103 
1104 
1105 /*
1106  * General init/exit code.
1107  */
1108 
1109 static int cmpc_init(void)
1110 {
1111 	int r;
1112 
1113 	r = acpi_bus_register_driver(&cmpc_keys_acpi_driver);
1114 	if (r)
1115 		goto failed_keys;
1116 
1117 	r = acpi_bus_register_driver(&cmpc_ipml_acpi_driver);
1118 	if (r)
1119 		goto failed_bl;
1120 
1121 	r = acpi_bus_register_driver(&cmpc_tablet_acpi_driver);
1122 	if (r)
1123 		goto failed_tablet;
1124 
1125 	r = acpi_bus_register_driver(&cmpc_accel_acpi_driver);
1126 	if (r)
1127 		goto failed_accel;
1128 
1129 	r = acpi_bus_register_driver(&cmpc_accel_acpi_driver_v4);
1130 	if (r)
1131 		goto failed_accel_v4;
1132 
1133 	return r;
1134 
1135 failed_accel_v4:
1136 	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
1137 
1138 failed_accel:
1139 	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
1140 
1141 failed_tablet:
1142 	acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
1143 
1144 failed_bl:
1145 	acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
1146 
1147 failed_keys:
1148 	return r;
1149 }
1150 
1151 static void cmpc_exit(void)
1152 {
1153 	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver_v4);
1154 	acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
1155 	acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
1156 	acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
1157 	acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
1158 }
1159 
1160 module_init(cmpc_init);
1161 module_exit(cmpc_exit);
1162 
1163 static const struct acpi_device_id cmpc_device_ids[] = {
1164 	{CMPC_ACCEL_HID, 0},
1165 	{CMPC_ACCEL_HID_V4, 0},
1166 	{CMPC_TABLET_HID, 0},
1167 	{CMPC_IPML_HID, 0},
1168 	{CMPC_KEYS_HID, 0},
1169 	{"", 0}
1170 };
1171 
1172 MODULE_DEVICE_TABLE(acpi, cmpc_device_ids);
1173