cgroup: superblock can't be released with active dentries
[firefly-linux-kernel-4.4.55.git] / drivers / platform / x86 / fujitsu-tablet.c
1 /*
2  * Copyright (C) 2006-2012 Robert Gerlach <khnz@gmx.de>
3  * Copyright (C) 2005-2006 Jan Rychter <jan@rychter.com>
4  *
5  * You can redistribute and/or modify this program under the terms of the
6  * GNU General Public License version 2 as published by the Free Software
7  * Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
12  * 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  * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA.
17  */
18
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/bitops.h>
23 #include <linux/io.h>
24 #include <linux/ioport.h>
25 #include <linux/acpi.h>
26 #include <linux/device.h>
27 #include <linux/interrupt.h>
28 #include <linux/input.h>
29 #include <linux/delay.h>
30 #include <linux/dmi.h>
31
32 #define MODULENAME "fujitsu-tablet"
33
34 #define ACPI_FUJITSU_CLASS "fujitsu"
35
36 #define INVERT_TABLET_MODE_BIT      0x01
37 #define FORCE_TABLET_MODE_IF_UNDOCK 0x02
38
39 #define KEYMAP_LEN 16
40
41 static const struct acpi_device_id fujitsu_ids[] = {
42         { .id = "FUJ02BD" },
43         { .id = "FUJ02BF" },
44         { .id = "" }
45 };
46
47 struct fujitsu_config {
48         unsigned short keymap[KEYMAP_LEN];
49         unsigned int quirks;
50 };
51
52 static unsigned short keymap_Lifebook_Tseries[KEYMAP_LEN] __initconst = {
53         KEY_RESERVED,
54         KEY_RESERVED,
55         KEY_RESERVED,
56         KEY_RESERVED,
57         KEY_SCROLLDOWN,
58         KEY_SCROLLUP,
59         KEY_DIRECTION,
60         KEY_LEFTCTRL,
61         KEY_BRIGHTNESSUP,
62         KEY_BRIGHTNESSDOWN,
63         KEY_BRIGHTNESS_ZERO,
64         KEY_RESERVED,
65         KEY_RESERVED,
66         KEY_RESERVED,
67         KEY_RESERVED,
68         KEY_LEFTALT
69 };
70
71 static unsigned short keymap_Lifebook_U810[KEYMAP_LEN] __initconst = {
72         KEY_RESERVED,
73         KEY_RESERVED,
74         KEY_RESERVED,
75         KEY_RESERVED,
76         KEY_PROG1,
77         KEY_PROG2,
78         KEY_DIRECTION,
79         KEY_RESERVED,
80         KEY_RESERVED,
81         KEY_RESERVED,
82         KEY_UP,
83         KEY_DOWN,
84         KEY_RESERVED,
85         KEY_RESERVED,
86         KEY_LEFTCTRL,
87         KEY_LEFTALT
88 };
89
90 static unsigned short keymap_Stylistic_Tseries[KEYMAP_LEN] __initconst = {
91         KEY_RESERVED,
92         KEY_RESERVED,
93         KEY_RESERVED,
94         KEY_RESERVED,
95         KEY_PRINT,
96         KEY_BACKSPACE,
97         KEY_SPACE,
98         KEY_ENTER,
99         KEY_BRIGHTNESSUP,
100         KEY_BRIGHTNESSDOWN,
101         KEY_DOWN,
102         KEY_UP,
103         KEY_SCROLLUP,
104         KEY_SCROLLDOWN,
105         KEY_LEFTCTRL,
106         KEY_LEFTALT
107 };
108
109 static unsigned short keymap_Stylistic_ST5xxx[KEYMAP_LEN] __initconst = {
110         KEY_RESERVED,
111         KEY_RESERVED,
112         KEY_RESERVED,
113         KEY_RESERVED,
114         KEY_MAIL,
115         KEY_DIRECTION,
116         KEY_ESC,
117         KEY_ENTER,
118         KEY_BRIGHTNESSUP,
119         KEY_BRIGHTNESSDOWN,
120         KEY_DOWN,
121         KEY_UP,
122         KEY_SCROLLUP,
123         KEY_SCROLLDOWN,
124         KEY_LEFTCTRL,
125         KEY_LEFTALT
126 };
127
128 static struct {
129         struct input_dev *idev;
130         struct fujitsu_config config;
131         unsigned long prev_keymask;
132
133         char phys[21];
134
135         int irq;
136         int io_base;
137         int io_length;
138 } fujitsu;
139
140 static u8 fujitsu_ack(void)
141 {
142         return inb(fujitsu.io_base + 2);
143 }
144
145 static u8 fujitsu_status(void)
146 {
147         return inb(fujitsu.io_base + 6);
148 }
149
150 static u8 fujitsu_read_register(const u8 addr)
151 {
152         outb(addr, fujitsu.io_base);
153         return inb(fujitsu.io_base + 4);
154 }
155
156 static void fujitsu_send_state(void)
157 {
158         int state;
159         int dock, tablet_mode;
160
161         state = fujitsu_read_register(0xdd);
162
163         dock = state & 0x02;
164
165         if ((fujitsu.config.quirks & FORCE_TABLET_MODE_IF_UNDOCK) && (!dock)) {
166                 tablet_mode = 1;
167         } else{
168                 tablet_mode = state & 0x01;
169                 if (fujitsu.config.quirks & INVERT_TABLET_MODE_BIT)
170                         tablet_mode = !tablet_mode;
171         }
172
173         input_report_switch(fujitsu.idev, SW_DOCK, dock);
174         input_report_switch(fujitsu.idev, SW_TABLET_MODE, tablet_mode);
175         input_sync(fujitsu.idev);
176 }
177
178 static void fujitsu_reset(void)
179 {
180         int timeout = 50;
181
182         fujitsu_ack();
183
184         while ((fujitsu_status() & 0x02) && (--timeout))
185                 msleep(20);
186
187         fujitsu_send_state();
188 }
189
190 static int __devinit input_fujitsu_setup(struct device *parent,
191                                          const char *name, const char *phys)
192 {
193         struct input_dev *idev;
194         int error;
195         int i;
196
197         idev = input_allocate_device();
198         if (!idev)
199                 return -ENOMEM;
200
201         idev->dev.parent = parent;
202         idev->phys = phys;
203         idev->name = name;
204         idev->id.bustype = BUS_HOST;
205         idev->id.vendor  = 0x1734;      /* Fujitsu Siemens Computer GmbH */
206         idev->id.product = 0x0001;
207         idev->id.version = 0x0101;
208
209         idev->keycode = fujitsu.config.keymap;
210         idev->keycodesize = sizeof(fujitsu.config.keymap[0]);
211         idev->keycodemax = ARRAY_SIZE(fujitsu.config.keymap);
212
213         __set_bit(EV_REP, idev->evbit);
214
215         for (i = 0; i < ARRAY_SIZE(fujitsu.config.keymap); i++)
216                 if (fujitsu.config.keymap[i])
217                         input_set_capability(idev, EV_KEY, fujitsu.config.keymap[i]);
218
219         input_set_capability(idev, EV_MSC, MSC_SCAN);
220
221         input_set_capability(idev, EV_SW, SW_DOCK);
222         input_set_capability(idev, EV_SW, SW_TABLET_MODE);
223
224         input_set_capability(idev, EV_SW, SW_DOCK);
225         input_set_capability(idev, EV_SW, SW_TABLET_MODE);
226
227         error = input_register_device(idev);
228         if (error) {
229                 input_free_device(idev);
230                 return error;
231         }
232
233         fujitsu.idev = idev;
234         return 0;
235 }
236
237 static void input_fujitsu_remove(void)
238 {
239         input_unregister_device(fujitsu.idev);
240 }
241
242 static irqreturn_t fujitsu_interrupt(int irq, void *dev_id)
243 {
244         unsigned long keymask, changed;
245         unsigned int keycode;
246         int pressed;
247         int i;
248
249         if (unlikely(!(fujitsu_status() & 0x01)))
250                 return IRQ_NONE;
251
252         fujitsu_send_state();
253
254         keymask  = fujitsu_read_register(0xde);
255         keymask |= fujitsu_read_register(0xdf) << 8;
256         keymask ^= 0xffff;
257
258         changed = keymask ^ fujitsu.prev_keymask;
259         if (changed) {
260                 fujitsu.prev_keymask = keymask;
261
262                 for_each_set_bit(i, &changed, KEYMAP_LEN) {
263                         keycode = fujitsu.config.keymap[i];
264                         pressed = keymask & changed & BIT(i);
265
266                         if (pressed)
267                                 input_event(fujitsu.idev, EV_MSC, MSC_SCAN, i);
268
269                         input_report_key(fujitsu.idev, keycode, pressed);
270                         input_sync(fujitsu.idev);
271                 }
272         }
273
274         fujitsu_ack();
275         return IRQ_HANDLED;
276 }
277
278 static int __devinit fujitsu_dmi_default(const struct dmi_system_id *dmi)
279 {
280         printk(KERN_INFO MODULENAME ": %s\n", dmi->ident);
281         memcpy(fujitsu.config.keymap, dmi->driver_data,
282                         sizeof(fujitsu.config.keymap));
283         return 1;
284 }
285
286 static int __devinit fujitsu_dmi_stylistic(const struct dmi_system_id *dmi)
287 {
288         fujitsu_dmi_default(dmi);
289         fujitsu.config.quirks |= FORCE_TABLET_MODE_IF_UNDOCK;
290         fujitsu.config.quirks |= INVERT_TABLET_MODE_BIT;
291         return 1;
292 }
293
294 static struct dmi_system_id dmi_ids[] __initconst = {
295         {
296                 .callback = fujitsu_dmi_default,
297                 .ident = "Fujitsu Siemens P/T Series",
298                 .matches = {
299                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
300                         DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK")
301                 },
302                 .driver_data = keymap_Lifebook_Tseries
303         },
304         {
305                 .callback = fujitsu_dmi_default,
306                 .ident = "Fujitsu Lifebook T Series",
307                 .matches = {
308                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
309                         DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook T")
310                 },
311                 .driver_data = keymap_Lifebook_Tseries
312         },
313         {
314                 .callback = fujitsu_dmi_stylistic,
315                 .ident = "Fujitsu Siemens Stylistic T Series",
316                 .matches = {
317                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
318                         DMI_MATCH(DMI_PRODUCT_NAME, "Stylistic T")
319                 },
320                 .driver_data = keymap_Stylistic_Tseries
321         },
322         {
323                 .callback = fujitsu_dmi_default,
324                 .ident = "Fujitsu LifeBook U810",
325                 .matches = {
326                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
327                         DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook U810")
328                 },
329                 .driver_data = keymap_Lifebook_U810
330         },
331         {
332                 .callback = fujitsu_dmi_stylistic,
333                 .ident = "Fujitsu Siemens Stylistic ST5xxx Series",
334                 .matches = {
335                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
336                         DMI_MATCH(DMI_PRODUCT_NAME, "STYLISTIC ST5")
337                 },
338                 .driver_data = keymap_Stylistic_ST5xxx
339         },
340         {
341                 .callback = fujitsu_dmi_stylistic,
342                 .ident = "Fujitsu Siemens Stylistic ST5xxx Series",
343                 .matches = {
344                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
345                         DMI_MATCH(DMI_PRODUCT_NAME, "Stylistic ST5")
346                 },
347                 .driver_data = keymap_Stylistic_ST5xxx
348         },
349         {
350                 .callback = fujitsu_dmi_default,
351                 .ident = "Unknown (using defaults)",
352                 .matches = {
353                         DMI_MATCH(DMI_SYS_VENDOR, ""),
354                         DMI_MATCH(DMI_PRODUCT_NAME, "")
355                 },
356                 .driver_data = keymap_Lifebook_Tseries
357         },
358         { NULL }
359 };
360
361 static acpi_status __devinit
362 fujitsu_walk_resources(struct acpi_resource *res, void *data)
363 {
364         switch (res->type) {
365         case ACPI_RESOURCE_TYPE_IRQ:
366                 fujitsu.irq = res->data.irq.interrupts[0];
367                 return AE_OK;
368
369         case ACPI_RESOURCE_TYPE_IO:
370                 fujitsu.io_base = res->data.io.minimum;
371                 fujitsu.io_length = res->data.io.address_length;
372                 return AE_OK;
373
374         case ACPI_RESOURCE_TYPE_END_TAG:
375                 if (fujitsu.irq && fujitsu.io_base)
376                         return AE_OK;
377                 else
378                         return AE_NOT_FOUND;
379
380         default:
381                 return AE_ERROR;
382         }
383 }
384
385 static int __devinit acpi_fujitsu_add(struct acpi_device *adev)
386 {
387         acpi_status status;
388         int error;
389
390         if (!adev)
391                 return -EINVAL;
392
393         status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
394                         fujitsu_walk_resources, NULL);
395         if (ACPI_FAILURE(status) || !fujitsu.irq || !fujitsu.io_base)
396                 return -ENODEV;
397
398         sprintf(acpi_device_name(adev), "Fujitsu %s", acpi_device_hid(adev));
399         sprintf(acpi_device_class(adev), "%s", ACPI_FUJITSU_CLASS);
400
401         snprintf(fujitsu.phys, sizeof(fujitsu.phys),
402                         "%s/input0", acpi_device_hid(adev));
403
404         error = input_fujitsu_setup(&adev->dev,
405                 acpi_device_name(adev), fujitsu.phys);
406         if (error)
407                 return error;
408
409         if (!request_region(fujitsu.io_base, fujitsu.io_length, MODULENAME)) {
410                 input_fujitsu_remove();
411                 return -EBUSY;
412         }
413
414         fujitsu_reset();
415
416         error = request_irq(fujitsu.irq, fujitsu_interrupt,
417                         IRQF_SHARED, MODULENAME, fujitsu_interrupt);
418         if (error) {
419                 release_region(fujitsu.io_base, fujitsu.io_length);
420                 input_fujitsu_remove();
421                 return error;
422         }
423
424         return 0;
425 }
426
427 static int __devexit acpi_fujitsu_remove(struct acpi_device *adev, int type)
428 {
429         free_irq(fujitsu.irq, fujitsu_interrupt);
430         release_region(fujitsu.io_base, fujitsu.io_length);
431         input_fujitsu_remove();
432         return 0;
433 }
434
435 static int acpi_fujitsu_resume(struct acpi_device *adev)
436 {
437         fujitsu_reset();
438         return 0;
439 }
440
441 static struct acpi_driver acpi_fujitsu_driver = {
442         .name  = MODULENAME,
443         .class = "hotkey",
444         .ids   = fujitsu_ids,
445         .ops   = {
446                 .add    = acpi_fujitsu_add,
447                 .remove = acpi_fujitsu_remove,
448                 .resume = acpi_fujitsu_resume,
449         }
450 };
451
452 static int __init fujitsu_module_init(void)
453 {
454         int error;
455
456         dmi_check_system(dmi_ids);
457
458         error = acpi_bus_register_driver(&acpi_fujitsu_driver);
459         if (error)
460                 return error;
461
462         return 0;
463 }
464
465 static void __exit fujitsu_module_exit(void)
466 {
467         acpi_bus_unregister_driver(&acpi_fujitsu_driver);
468 }
469
470 module_init(fujitsu_module_init);
471 module_exit(fujitsu_module_exit);
472
473 MODULE_AUTHOR("Robert Gerlach <khnz@gmx.de>");
474 MODULE_DESCRIPTION("Fujitsu tablet pc extras driver");
475 MODULE_LICENSE("GPL");
476 MODULE_VERSION("2.4");
477
478 MODULE_DEVICE_TABLE(acpi, fujitsu_ids);