0001
0002
0003
0004
0005
0006
0007 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0008
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/init.h>
0012 #include <linux/bitops.h>
0013 #include <linux/io.h>
0014 #include <linux/ioport.h>
0015 #include <linux/acpi.h>
0016 #include <linux/device.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/input.h>
0019 #include <linux/delay.h>
0020 #include <linux/dmi.h>
0021
0022 #define MODULENAME "fujitsu-tablet"
0023
0024 #define ACPI_FUJITSU_CLASS "fujitsu"
0025
0026 #define INVERT_TABLET_MODE_BIT 0x01
0027 #define INVERT_DOCK_STATE_BIT 0x02
0028 #define FORCE_TABLET_MODE_IF_UNDOCK 0x04
0029
0030 #define KEYMAP_LEN 16
0031
0032 static const struct acpi_device_id fujitsu_ids[] = {
0033 { .id = "FUJ02BD" },
0034 { .id = "FUJ02BF" },
0035 { .id = "" }
0036 };
0037
0038 struct fujitsu_config {
0039 unsigned short keymap[KEYMAP_LEN];
0040 unsigned int quirks;
0041 };
0042
0043 static unsigned short keymap_Lifebook_Tseries[KEYMAP_LEN] __initdata = {
0044 KEY_RESERVED,
0045 KEY_RESERVED,
0046 KEY_RESERVED,
0047 KEY_RESERVED,
0048 KEY_SCROLLDOWN,
0049 KEY_SCROLLUP,
0050 KEY_ROTATE_DISPLAY,
0051 KEY_LEFTCTRL,
0052 KEY_BRIGHTNESSUP,
0053 KEY_BRIGHTNESSDOWN,
0054 KEY_BRIGHTNESS_ZERO,
0055 KEY_RESERVED,
0056 KEY_RESERVED,
0057 KEY_RESERVED,
0058 KEY_RESERVED,
0059 KEY_LEFTALT
0060 };
0061
0062 static unsigned short keymap_Lifebook_T901[KEYMAP_LEN] __initdata = {
0063 KEY_RESERVED,
0064 KEY_RESERVED,
0065 KEY_RESERVED,
0066 KEY_RESERVED,
0067 KEY_SCROLLDOWN,
0068 KEY_SCROLLUP,
0069 KEY_CYCLEWINDOWS,
0070 KEY_LEFTCTRL,
0071 KEY_RESERVED,
0072 KEY_RESERVED,
0073 KEY_RESERVED,
0074 KEY_RESERVED,
0075 KEY_RESERVED,
0076 KEY_RESERVED,
0077 KEY_RESERVED,
0078 KEY_LEFTMETA
0079 };
0080
0081 static unsigned short keymap_Lifebook_T902[KEYMAP_LEN] __initdata = {
0082 KEY_RESERVED,
0083 KEY_VOLUMEDOWN,
0084 KEY_VOLUMEUP,
0085 KEY_CYCLEWINDOWS,
0086 KEY_PROG1,
0087 KEY_PROG2,
0088 KEY_LEFTMETA,
0089 KEY_RESERVED,
0090 KEY_RESERVED,
0091 KEY_RESERVED,
0092 KEY_RESERVED,
0093 KEY_RESERVED,
0094 KEY_RESERVED,
0095 KEY_RESERVED,
0096 KEY_RESERVED,
0097 KEY_RESERVED,
0098 };
0099
0100 static unsigned short keymap_Lifebook_U810[KEYMAP_LEN] __initdata = {
0101 KEY_RESERVED,
0102 KEY_RESERVED,
0103 KEY_RESERVED,
0104 KEY_RESERVED,
0105 KEY_PROG1,
0106 KEY_PROG2,
0107 KEY_ROTATE_DISPLAY,
0108 KEY_RESERVED,
0109 KEY_RESERVED,
0110 KEY_RESERVED,
0111 KEY_UP,
0112 KEY_DOWN,
0113 KEY_RESERVED,
0114 KEY_RESERVED,
0115 KEY_LEFTCTRL,
0116 KEY_LEFTALT
0117 };
0118
0119 static unsigned short keymap_Stylistic_Tseries[KEYMAP_LEN] __initdata = {
0120 KEY_RESERVED,
0121 KEY_RESERVED,
0122 KEY_RESERVED,
0123 KEY_RESERVED,
0124 KEY_PRINT,
0125 KEY_BACKSPACE,
0126 KEY_SPACE,
0127 KEY_ENTER,
0128 KEY_BRIGHTNESSUP,
0129 KEY_BRIGHTNESSDOWN,
0130 KEY_DOWN,
0131 KEY_UP,
0132 KEY_SCROLLUP,
0133 KEY_SCROLLDOWN,
0134 KEY_LEFTCTRL,
0135 KEY_LEFTALT
0136 };
0137
0138 static unsigned short keymap_Stylistic_ST5xxx[KEYMAP_LEN] __initdata = {
0139 KEY_RESERVED,
0140 KEY_RESERVED,
0141 KEY_RESERVED,
0142 KEY_RESERVED,
0143 KEY_MAIL,
0144 KEY_ROTATE_DISPLAY,
0145 KEY_ESC,
0146 KEY_ENTER,
0147 KEY_BRIGHTNESSUP,
0148 KEY_BRIGHTNESSDOWN,
0149 KEY_DOWN,
0150 KEY_UP,
0151 KEY_SCROLLUP,
0152 KEY_SCROLLDOWN,
0153 KEY_LEFTCTRL,
0154 KEY_LEFTALT
0155 };
0156
0157 static struct {
0158 struct input_dev *idev;
0159 struct fujitsu_config config;
0160 unsigned long prev_keymask;
0161
0162 char phys[21];
0163
0164 int irq;
0165 int io_base;
0166 int io_length;
0167 } fujitsu;
0168
0169 static u8 fujitsu_ack(void)
0170 {
0171 return inb(fujitsu.io_base + 2);
0172 }
0173
0174 static u8 fujitsu_status(void)
0175 {
0176 return inb(fujitsu.io_base + 6);
0177 }
0178
0179 static u8 fujitsu_read_register(const u8 addr)
0180 {
0181 outb(addr, fujitsu.io_base);
0182 return inb(fujitsu.io_base + 4);
0183 }
0184
0185 static void fujitsu_send_state(void)
0186 {
0187 int state;
0188 int dock, tablet_mode;
0189
0190 state = fujitsu_read_register(0xdd);
0191
0192 dock = state & 0x02;
0193 if (fujitsu.config.quirks & INVERT_DOCK_STATE_BIT)
0194 dock = !dock;
0195
0196 if ((fujitsu.config.quirks & FORCE_TABLET_MODE_IF_UNDOCK) && (!dock)) {
0197 tablet_mode = 1;
0198 } else{
0199 tablet_mode = state & 0x01;
0200 if (fujitsu.config.quirks & INVERT_TABLET_MODE_BIT)
0201 tablet_mode = !tablet_mode;
0202 }
0203
0204 input_report_switch(fujitsu.idev, SW_DOCK, dock);
0205 input_report_switch(fujitsu.idev, SW_TABLET_MODE, tablet_mode);
0206 input_sync(fujitsu.idev);
0207 }
0208
0209 static void fujitsu_reset(void)
0210 {
0211 int timeout = 50;
0212
0213 fujitsu_ack();
0214
0215 while ((fujitsu_status() & 0x02) && (--timeout))
0216 msleep(20);
0217
0218 fujitsu_send_state();
0219 }
0220
0221 static int input_fujitsu_setup(struct device *parent, const char *name,
0222 const char *phys)
0223 {
0224 struct input_dev *idev;
0225 int error;
0226 int i;
0227
0228 idev = input_allocate_device();
0229 if (!idev)
0230 return -ENOMEM;
0231
0232 idev->dev.parent = parent;
0233 idev->phys = phys;
0234 idev->name = name;
0235 idev->id.bustype = BUS_HOST;
0236 idev->id.vendor = 0x1734;
0237 idev->id.product = 0x0001;
0238 idev->id.version = 0x0101;
0239
0240 idev->keycode = fujitsu.config.keymap;
0241 idev->keycodesize = sizeof(fujitsu.config.keymap[0]);
0242 idev->keycodemax = ARRAY_SIZE(fujitsu.config.keymap);
0243
0244 __set_bit(EV_REP, idev->evbit);
0245
0246 for (i = 0; i < ARRAY_SIZE(fujitsu.config.keymap); i++)
0247 if (fujitsu.config.keymap[i])
0248 input_set_capability(idev, EV_KEY, fujitsu.config.keymap[i]);
0249
0250 input_set_capability(idev, EV_MSC, MSC_SCAN);
0251
0252 input_set_capability(idev, EV_SW, SW_DOCK);
0253 input_set_capability(idev, EV_SW, SW_TABLET_MODE);
0254
0255 error = input_register_device(idev);
0256 if (error) {
0257 input_free_device(idev);
0258 return error;
0259 }
0260
0261 fujitsu.idev = idev;
0262 return 0;
0263 }
0264
0265 static void input_fujitsu_remove(void)
0266 {
0267 input_unregister_device(fujitsu.idev);
0268 }
0269
0270 static irqreturn_t fujitsu_interrupt(int irq, void *dev_id)
0271 {
0272 unsigned long keymask, changed;
0273 unsigned int keycode;
0274 int pressed;
0275 int i;
0276
0277 if (unlikely(!(fujitsu_status() & 0x01)))
0278 return IRQ_NONE;
0279
0280 fujitsu_send_state();
0281
0282 keymask = fujitsu_read_register(0xde);
0283 keymask |= fujitsu_read_register(0xdf) << 8;
0284 keymask ^= 0xffff;
0285
0286 changed = keymask ^ fujitsu.prev_keymask;
0287 if (changed) {
0288 fujitsu.prev_keymask = keymask;
0289
0290 for_each_set_bit(i, &changed, KEYMAP_LEN) {
0291 keycode = fujitsu.config.keymap[i];
0292 pressed = keymask & changed & BIT(i);
0293
0294 if (pressed)
0295 input_event(fujitsu.idev, EV_MSC, MSC_SCAN, i);
0296
0297 input_report_key(fujitsu.idev, keycode, pressed);
0298 input_sync(fujitsu.idev);
0299 }
0300 }
0301
0302 fujitsu_ack();
0303 return IRQ_HANDLED;
0304 }
0305
0306 static void __init fujitsu_dmi_common(const struct dmi_system_id *dmi)
0307 {
0308 pr_info("%s\n", dmi->ident);
0309 memcpy(fujitsu.config.keymap, dmi->driver_data,
0310 sizeof(fujitsu.config.keymap));
0311 }
0312
0313 static int __init fujitsu_dmi_lifebook(const struct dmi_system_id *dmi)
0314 {
0315 fujitsu_dmi_common(dmi);
0316 fujitsu.config.quirks |= INVERT_TABLET_MODE_BIT;
0317 return 1;
0318 }
0319
0320 static int __init fujitsu_dmi_stylistic(const struct dmi_system_id *dmi)
0321 {
0322 fujitsu_dmi_common(dmi);
0323 fujitsu.config.quirks |= FORCE_TABLET_MODE_IF_UNDOCK;
0324 fujitsu.config.quirks |= INVERT_DOCK_STATE_BIT;
0325 return 1;
0326 }
0327
0328 static const struct dmi_system_id dmi_ids[] __initconst = {
0329 {
0330 .callback = fujitsu_dmi_lifebook,
0331 .ident = "Fujitsu Lifebook T901",
0332 .matches = {
0333 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0334 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook T901")
0335 },
0336 .driver_data = keymap_Lifebook_T901
0337 },
0338 {
0339 .callback = fujitsu_dmi_lifebook,
0340 .ident = "Fujitsu Lifebook T901",
0341 .matches = {
0342 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0343 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T901")
0344 },
0345 .driver_data = keymap_Lifebook_T901
0346 },
0347 {
0348 .callback = fujitsu_dmi_lifebook,
0349 .ident = "Fujitsu Lifebook T902",
0350 .matches = {
0351 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0352 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T902")
0353 },
0354 .driver_data = keymap_Lifebook_T902
0355 },
0356 {
0357 .callback = fujitsu_dmi_lifebook,
0358 .ident = "Fujitsu Siemens P/T Series",
0359 .matches = {
0360 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0361 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK")
0362 },
0363 .driver_data = keymap_Lifebook_Tseries
0364 },
0365 {
0366 .callback = fujitsu_dmi_lifebook,
0367 .ident = "Fujitsu Lifebook T Series",
0368 .matches = {
0369 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0370 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook T")
0371 },
0372 .driver_data = keymap_Lifebook_Tseries
0373 },
0374 {
0375 .callback = fujitsu_dmi_stylistic,
0376 .ident = "Fujitsu Siemens Stylistic T Series",
0377 .matches = {
0378 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0379 DMI_MATCH(DMI_PRODUCT_NAME, "Stylistic T")
0380 },
0381 .driver_data = keymap_Stylistic_Tseries
0382 },
0383 {
0384 .callback = fujitsu_dmi_lifebook,
0385 .ident = "Fujitsu LifeBook U810",
0386 .matches = {
0387 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0388 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook U810")
0389 },
0390 .driver_data = keymap_Lifebook_U810
0391 },
0392 {
0393 .callback = fujitsu_dmi_stylistic,
0394 .ident = "Fujitsu Siemens Stylistic ST5xxx Series",
0395 .matches = {
0396 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0397 DMI_MATCH(DMI_PRODUCT_NAME, "STYLISTIC ST5")
0398 },
0399 .driver_data = keymap_Stylistic_ST5xxx
0400 },
0401 {
0402 .callback = fujitsu_dmi_stylistic,
0403 .ident = "Fujitsu Siemens Stylistic ST5xxx Series",
0404 .matches = {
0405 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0406 DMI_MATCH(DMI_PRODUCT_NAME, "Stylistic ST5")
0407 },
0408 .driver_data = keymap_Stylistic_ST5xxx
0409 },
0410 {
0411 .callback = fujitsu_dmi_lifebook,
0412 .ident = "Unknown (using defaults)",
0413 .matches = {
0414 DMI_MATCH(DMI_SYS_VENDOR, ""),
0415 DMI_MATCH(DMI_PRODUCT_NAME, "")
0416 },
0417 .driver_data = keymap_Lifebook_Tseries
0418 },
0419 { NULL }
0420 };
0421
0422 static acpi_status fujitsu_walk_resources(struct acpi_resource *res, void *data)
0423 {
0424 switch (res->type) {
0425 case ACPI_RESOURCE_TYPE_IRQ:
0426 fujitsu.irq = res->data.irq.interrupts[0];
0427 return AE_OK;
0428
0429 case ACPI_RESOURCE_TYPE_IO:
0430 fujitsu.io_base = res->data.io.minimum;
0431 fujitsu.io_length = res->data.io.address_length;
0432 return AE_OK;
0433
0434 case ACPI_RESOURCE_TYPE_END_TAG:
0435 if (fujitsu.irq && fujitsu.io_base)
0436 return AE_OK;
0437 else
0438 return AE_NOT_FOUND;
0439
0440 default:
0441 return AE_ERROR;
0442 }
0443 }
0444
0445 static int acpi_fujitsu_add(struct acpi_device *adev)
0446 {
0447 acpi_status status;
0448 int error;
0449
0450 if (!adev)
0451 return -EINVAL;
0452
0453 status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
0454 fujitsu_walk_resources, NULL);
0455 if (ACPI_FAILURE(status) || !fujitsu.irq || !fujitsu.io_base)
0456 return -ENODEV;
0457
0458 sprintf(acpi_device_name(adev), "Fujitsu %s", acpi_device_hid(adev));
0459 sprintf(acpi_device_class(adev), "%s", ACPI_FUJITSU_CLASS);
0460
0461 snprintf(fujitsu.phys, sizeof(fujitsu.phys),
0462 "%s/input0", acpi_device_hid(adev));
0463
0464 error = input_fujitsu_setup(&adev->dev,
0465 acpi_device_name(adev), fujitsu.phys);
0466 if (error)
0467 return error;
0468
0469 if (!request_region(fujitsu.io_base, fujitsu.io_length, MODULENAME)) {
0470 input_fujitsu_remove();
0471 return -EBUSY;
0472 }
0473
0474 fujitsu_reset();
0475
0476 error = request_irq(fujitsu.irq, fujitsu_interrupt,
0477 IRQF_SHARED, MODULENAME, fujitsu_interrupt);
0478 if (error) {
0479 release_region(fujitsu.io_base, fujitsu.io_length);
0480 input_fujitsu_remove();
0481 return error;
0482 }
0483
0484 return 0;
0485 }
0486
0487 static int acpi_fujitsu_remove(struct acpi_device *adev)
0488 {
0489 free_irq(fujitsu.irq, fujitsu_interrupt);
0490 release_region(fujitsu.io_base, fujitsu.io_length);
0491 input_fujitsu_remove();
0492 return 0;
0493 }
0494
0495 #ifdef CONFIG_PM_SLEEP
0496 static int acpi_fujitsu_resume(struct device *dev)
0497 {
0498 fujitsu_reset();
0499 return 0;
0500 }
0501 #endif
0502
0503 static SIMPLE_DEV_PM_OPS(acpi_fujitsu_pm, NULL, acpi_fujitsu_resume);
0504
0505 static struct acpi_driver acpi_fujitsu_driver = {
0506 .name = MODULENAME,
0507 .class = "hotkey",
0508 .ids = fujitsu_ids,
0509 .ops = {
0510 .add = acpi_fujitsu_add,
0511 .remove = acpi_fujitsu_remove,
0512 },
0513 .drv.pm = &acpi_fujitsu_pm,
0514 };
0515
0516 static int __init fujitsu_module_init(void)
0517 {
0518 int error;
0519
0520 dmi_check_system(dmi_ids);
0521
0522 error = acpi_bus_register_driver(&acpi_fujitsu_driver);
0523 if (error)
0524 return error;
0525
0526 return 0;
0527 }
0528
0529 static void __exit fujitsu_module_exit(void)
0530 {
0531 acpi_bus_unregister_driver(&acpi_fujitsu_driver);
0532 }
0533
0534 module_init(fujitsu_module_init);
0535 module_exit(fujitsu_module_exit);
0536
0537 MODULE_AUTHOR("Robert Gerlach <khnz@gmx.de>");
0538 MODULE_DESCRIPTION("Fujitsu tablet pc extras driver");
0539 MODULE_LICENSE("GPL");
0540 MODULE_VERSION("2.5");
0541
0542 MODULE_DEVICE_TABLE(acpi, fujitsu_ids);