0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/acpi.h>
0017 #include <linux/hid.h>
0018 #include <linux/input/vivaldi-fmap.h>
0019 #include <linux/leds.h>
0020 #include <linux/module.h>
0021 #include <linux/of.h>
0022 #include <linux/platform_data/cros_ec_commands.h>
0023 #include <linux/platform_data/cros_ec_proto.h>
0024 #include <linux/platform_device.h>
0025 #include <linux/pm_wakeup.h>
0026 #include <asm/unaligned.h>
0027
0028 #include "hid-ids.h"
0029 #include "hid-vivaldi-common.h"
0030
0031
0032
0033
0034
0035
0036
0037 struct cbas_ec {
0038 struct device *dev;
0039 struct input_dev *input;
0040 bool base_present;
0041 bool base_folded;
0042 struct notifier_block notifier;
0043 };
0044
0045 static struct cbas_ec cbas_ec;
0046 static DEFINE_SPINLOCK(cbas_ec_lock);
0047 static DEFINE_MUTEX(cbas_ec_reglock);
0048
0049 static bool cbas_parse_base_state(const void *data)
0050 {
0051 u32 switches = get_unaligned_le32(data);
0052
0053 return !!(switches & BIT(EC_MKBP_BASE_ATTACHED));
0054 }
0055
0056 static int cbas_ec_query_base(struct cros_ec_device *ec_dev, bool get_state,
0057 bool *state)
0058 {
0059 struct ec_params_mkbp_info *params;
0060 struct cros_ec_command *msg;
0061 int ret;
0062
0063 msg = kzalloc(struct_size(msg, data, max(sizeof(u32), sizeof(*params))),
0064 GFP_KERNEL);
0065 if (!msg)
0066 return -ENOMEM;
0067
0068 msg->command = EC_CMD_MKBP_INFO;
0069 msg->version = 1;
0070 msg->outsize = sizeof(*params);
0071 msg->insize = sizeof(u32);
0072 params = (struct ec_params_mkbp_info *)msg->data;
0073 params->info_type = get_state ?
0074 EC_MKBP_INFO_CURRENT : EC_MKBP_INFO_SUPPORTED;
0075 params->event_type = EC_MKBP_EVENT_SWITCH;
0076
0077 ret = cros_ec_cmd_xfer_status(ec_dev, msg);
0078 if (ret >= 0) {
0079 if (ret != sizeof(u32)) {
0080 dev_warn(ec_dev->dev, "wrong result size: %d != %zu\n",
0081 ret, sizeof(u32));
0082 ret = -EPROTO;
0083 } else {
0084 *state = cbas_parse_base_state(msg->data);
0085 ret = 0;
0086 }
0087 }
0088
0089 kfree(msg);
0090
0091 return ret;
0092 }
0093
0094 static int cbas_ec_notify(struct notifier_block *nb,
0095 unsigned long queued_during_suspend,
0096 void *_notify)
0097 {
0098 struct cros_ec_device *ec = _notify;
0099 unsigned long flags;
0100 bool base_present;
0101
0102 if (ec->event_data.event_type == EC_MKBP_EVENT_SWITCH) {
0103 base_present = cbas_parse_base_state(
0104 &ec->event_data.data.switches);
0105 dev_dbg(cbas_ec.dev,
0106 "%s: base: %d\n", __func__, base_present);
0107
0108 if (device_may_wakeup(cbas_ec.dev) ||
0109 !queued_during_suspend) {
0110
0111 pm_wakeup_event(cbas_ec.dev, 0);
0112
0113 spin_lock_irqsave(&cbas_ec_lock, flags);
0114
0115
0116
0117
0118
0119
0120
0121
0122 if (base_present != cbas_ec.base_present) {
0123 input_report_switch(cbas_ec.input,
0124 SW_TABLET_MODE,
0125 !base_present);
0126 input_sync(cbas_ec.input);
0127 cbas_ec.base_present = base_present;
0128 }
0129
0130 spin_unlock_irqrestore(&cbas_ec_lock, flags);
0131 }
0132 }
0133
0134 return NOTIFY_OK;
0135 }
0136
0137 static __maybe_unused int cbas_ec_resume(struct device *dev)
0138 {
0139 struct cros_ec_device *ec = dev_get_drvdata(dev->parent);
0140 bool base_present;
0141 int error;
0142
0143 error = cbas_ec_query_base(ec, true, &base_present);
0144 if (error) {
0145 dev_warn(dev, "failed to fetch base state on resume: %d\n",
0146 error);
0147 } else {
0148 spin_lock_irq(&cbas_ec_lock);
0149
0150 cbas_ec.base_present = base_present;
0151
0152
0153
0154
0155
0156
0157 if (!cbas_ec.base_present) {
0158 input_report_switch(cbas_ec.input, SW_TABLET_MODE, 1);
0159 input_sync(cbas_ec.input);
0160 }
0161
0162 spin_unlock_irq(&cbas_ec_lock);
0163 }
0164
0165 return 0;
0166 }
0167
0168 static SIMPLE_DEV_PM_OPS(cbas_ec_pm_ops, NULL, cbas_ec_resume);
0169
0170 static void cbas_ec_set_input(struct input_dev *input)
0171 {
0172
0173 spin_lock_irq(&cbas_ec_lock);
0174 cbas_ec.input = input;
0175 spin_unlock_irq(&cbas_ec_lock);
0176 }
0177
0178 static int __cbas_ec_probe(struct platform_device *pdev)
0179 {
0180 struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
0181 struct input_dev *input;
0182 bool base_supported;
0183 int error;
0184
0185 error = cbas_ec_query_base(ec, false, &base_supported);
0186 if (error)
0187 return error;
0188
0189 if (!base_supported)
0190 return -ENXIO;
0191
0192 input = devm_input_allocate_device(&pdev->dev);
0193 if (!input)
0194 return -ENOMEM;
0195
0196 input->name = "Whiskers Tablet Mode Switch";
0197 input->id.bustype = BUS_HOST;
0198
0199 input_set_capability(input, EV_SW, SW_TABLET_MODE);
0200
0201 error = input_register_device(input);
0202 if (error) {
0203 dev_err(&pdev->dev, "cannot register input device: %d\n",
0204 error);
0205 return error;
0206 }
0207
0208
0209 error = cbas_ec_query_base(ec, true, &cbas_ec.base_present);
0210 if (error) {
0211 dev_err(&pdev->dev, "cannot query base state: %d\n", error);
0212 return error;
0213 }
0214
0215 if (!cbas_ec.base_present)
0216 cbas_ec.base_folded = false;
0217
0218 dev_dbg(&pdev->dev, "%s: base: %d, folded: %d\n", __func__,
0219 cbas_ec.base_present, cbas_ec.base_folded);
0220
0221 input_report_switch(input, SW_TABLET_MODE,
0222 !cbas_ec.base_present || cbas_ec.base_folded);
0223
0224 cbas_ec_set_input(input);
0225
0226 cbas_ec.dev = &pdev->dev;
0227 cbas_ec.notifier.notifier_call = cbas_ec_notify;
0228 error = blocking_notifier_chain_register(&ec->event_notifier,
0229 &cbas_ec.notifier);
0230 if (error) {
0231 dev_err(&pdev->dev, "cannot register notifier: %d\n", error);
0232 cbas_ec_set_input(NULL);
0233 return error;
0234 }
0235
0236 device_init_wakeup(&pdev->dev, true);
0237 return 0;
0238 }
0239
0240 static int cbas_ec_probe(struct platform_device *pdev)
0241 {
0242 int retval;
0243
0244 mutex_lock(&cbas_ec_reglock);
0245
0246 if (cbas_ec.input) {
0247 retval = -EBUSY;
0248 goto out;
0249 }
0250
0251 retval = __cbas_ec_probe(pdev);
0252
0253 out:
0254 mutex_unlock(&cbas_ec_reglock);
0255 return retval;
0256 }
0257
0258 static int cbas_ec_remove(struct platform_device *pdev)
0259 {
0260 struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
0261
0262 mutex_lock(&cbas_ec_reglock);
0263
0264 blocking_notifier_chain_unregister(&ec->event_notifier,
0265 &cbas_ec.notifier);
0266 cbas_ec_set_input(NULL);
0267
0268 mutex_unlock(&cbas_ec_reglock);
0269 return 0;
0270 }
0271
0272 static const struct acpi_device_id cbas_ec_acpi_ids[] = {
0273 { "GOOG000B", 0 },
0274 { }
0275 };
0276 MODULE_DEVICE_TABLE(acpi, cbas_ec_acpi_ids);
0277
0278 #ifdef CONFIG_OF
0279 static const struct of_device_id cbas_ec_of_match[] = {
0280 { .compatible = "google,cros-cbas" },
0281 { },
0282 };
0283 MODULE_DEVICE_TABLE(of, cbas_ec_of_match);
0284 #endif
0285
0286 static struct platform_driver cbas_ec_driver = {
0287 .probe = cbas_ec_probe,
0288 .remove = cbas_ec_remove,
0289 .driver = {
0290 .name = "cbas_ec",
0291 .acpi_match_table = ACPI_PTR(cbas_ec_acpi_ids),
0292 .of_match_table = of_match_ptr(cbas_ec_of_match),
0293 .pm = &cbas_ec_pm_ops,
0294 },
0295 };
0296
0297 #define MAX_BRIGHTNESS 100
0298
0299 struct hammer_kbd_leds {
0300 struct led_classdev cdev;
0301 struct hid_device *hdev;
0302 u8 buf[2] ____cacheline_aligned;
0303 };
0304
0305 static int hammer_kbd_brightness_set_blocking(struct led_classdev *cdev,
0306 enum led_brightness br)
0307 {
0308 struct hammer_kbd_leds *led = container_of(cdev,
0309 struct hammer_kbd_leds,
0310 cdev);
0311 int ret;
0312
0313 led->buf[0] = 0;
0314 led->buf[1] = br;
0315
0316
0317
0318
0319
0320 ret = hid_hw_power(led->hdev, PM_HINT_FULLON);
0321 if (ret < 0) {
0322 hid_err(led->hdev, "failed: device not resumed %d\n", ret);
0323 return ret;
0324 }
0325
0326 ret = hid_hw_output_report(led->hdev, led->buf, sizeof(led->buf));
0327 if (ret == -ENOSYS)
0328 ret = hid_hw_raw_request(led->hdev, 0, led->buf,
0329 sizeof(led->buf),
0330 HID_OUTPUT_REPORT,
0331 HID_REQ_SET_REPORT);
0332 if (ret < 0)
0333 hid_err(led->hdev, "failed to set keyboard backlight: %d\n",
0334 ret);
0335
0336
0337 hid_hw_power(led->hdev, PM_HINT_NORMAL);
0338
0339 return ret;
0340 }
0341
0342 static int hammer_register_leds(struct hid_device *hdev)
0343 {
0344 struct hammer_kbd_leds *kbd_backlight;
0345
0346 kbd_backlight = devm_kzalloc(&hdev->dev, sizeof(*kbd_backlight),
0347 GFP_KERNEL);
0348 if (!kbd_backlight)
0349 return -ENOMEM;
0350
0351 kbd_backlight->hdev = hdev;
0352 kbd_backlight->cdev.name = "hammer::kbd_backlight";
0353 kbd_backlight->cdev.max_brightness = MAX_BRIGHTNESS;
0354 kbd_backlight->cdev.brightness_set_blocking =
0355 hammer_kbd_brightness_set_blocking;
0356 kbd_backlight->cdev.flags = LED_HW_PLUGGABLE;
0357
0358
0359 hammer_kbd_brightness_set_blocking(&kbd_backlight->cdev, 0);
0360
0361 return devm_led_classdev_register(&hdev->dev, &kbd_backlight->cdev);
0362 }
0363
0364 #define HID_UP_GOOGLEVENDOR 0xffd10000
0365 #define HID_VD_KBD_FOLDED 0x00000019
0366 #define HID_USAGE_KBD_FOLDED (HID_UP_GOOGLEVENDOR | HID_VD_KBD_FOLDED)
0367
0368
0369 #define HID_AD_BRIGHTNESS 0x00140046
0370
0371 static int hammer_input_mapping(struct hid_device *hdev, struct hid_input *hi,
0372 struct hid_field *field,
0373 struct hid_usage *usage,
0374 unsigned long **bit, int *max)
0375 {
0376 if (usage->hid == HID_USAGE_KBD_FOLDED) {
0377
0378
0379
0380
0381
0382 return -1;
0383 }
0384
0385 return 0;
0386 }
0387
0388 static void hammer_folded_event(struct hid_device *hdev, bool folded)
0389 {
0390 unsigned long flags;
0391
0392 spin_lock_irqsave(&cbas_ec_lock, flags);
0393
0394
0395
0396
0397
0398 cbas_ec.base_present = true;
0399 cbas_ec.base_folded = folded;
0400 hid_dbg(hdev, "%s: base: %d, folded: %d\n", __func__,
0401 cbas_ec.base_present, cbas_ec.base_folded);
0402
0403 if (cbas_ec.input) {
0404 input_report_switch(cbas_ec.input, SW_TABLET_MODE, folded);
0405 input_sync(cbas_ec.input);
0406 }
0407
0408 spin_unlock_irqrestore(&cbas_ec_lock, flags);
0409 }
0410
0411 static int hammer_event(struct hid_device *hid, struct hid_field *field,
0412 struct hid_usage *usage, __s32 value)
0413 {
0414 if (usage->hid == HID_USAGE_KBD_FOLDED) {
0415 hammer_folded_event(hid, value);
0416 return 1;
0417 }
0418
0419 return 0;
0420 }
0421
0422 static bool hammer_has_usage(struct hid_device *hdev, unsigned int report_type,
0423 unsigned application, unsigned usage)
0424 {
0425 struct hid_report_enum *re = &hdev->report_enum[report_type];
0426 struct hid_report *report;
0427 int i, j;
0428
0429 list_for_each_entry(report, &re->report_list, list) {
0430 if (report->application != application)
0431 continue;
0432
0433 for (i = 0; i < report->maxfield; i++) {
0434 struct hid_field *field = report->field[i];
0435
0436 for (j = 0; j < field->maxusage; j++)
0437 if (field->usage[j].hid == usage)
0438 return true;
0439 }
0440 }
0441
0442 return false;
0443 }
0444
0445 static bool hammer_has_folded_event(struct hid_device *hdev)
0446 {
0447 return hammer_has_usage(hdev, HID_INPUT_REPORT,
0448 HID_GD_KEYBOARD, HID_USAGE_KBD_FOLDED);
0449 }
0450
0451 static bool hammer_has_backlight_control(struct hid_device *hdev)
0452 {
0453 return hammer_has_usage(hdev, HID_OUTPUT_REPORT,
0454 HID_GD_KEYBOARD, HID_AD_BRIGHTNESS);
0455 }
0456
0457 static void hammer_get_folded_state(struct hid_device *hdev)
0458 {
0459 struct hid_report *report;
0460 char *buf;
0461 int len, rlen;
0462 int a;
0463
0464 report = hdev->report_enum[HID_INPUT_REPORT].report_id_hash[0x0];
0465
0466 if (!report || report->maxfield < 1)
0467 return;
0468
0469 len = hid_report_len(report) + 1;
0470
0471 buf = kmalloc(len, GFP_KERNEL);
0472 if (!buf)
0473 return;
0474
0475 rlen = hid_hw_raw_request(hdev, report->id, buf, len, report->type, HID_REQ_GET_REPORT);
0476
0477 if (rlen != len) {
0478 hid_warn(hdev, "Unable to read base folded state: %d (expected %d)\n", rlen, len);
0479 goto out;
0480 }
0481
0482 for (a = 0; a < report->maxfield; a++) {
0483 struct hid_field *field = report->field[a];
0484
0485 if (field->usage->hid == HID_USAGE_KBD_FOLDED) {
0486 u32 value = hid_field_extract(hdev, buf+1,
0487 field->report_offset, field->report_size);
0488
0489 hammer_folded_event(hdev, value);
0490 break;
0491 }
0492 }
0493
0494 out:
0495 kfree(buf);
0496 }
0497
0498 static void hammer_stop(void *hdev)
0499 {
0500 hid_hw_stop(hdev);
0501 }
0502
0503 static int hammer_probe(struct hid_device *hdev,
0504 const struct hid_device_id *id)
0505 {
0506 struct vivaldi_data *vdata;
0507 int error;
0508
0509 vdata = devm_kzalloc(&hdev->dev, sizeof(*vdata), GFP_KERNEL);
0510 if (!vdata)
0511 return -ENOMEM;
0512
0513 hid_set_drvdata(hdev, vdata);
0514
0515 error = hid_parse(hdev);
0516 if (error)
0517 return error;
0518
0519 error = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
0520 if (error)
0521 return error;
0522
0523 error = devm_add_action(&hdev->dev, hammer_stop, hdev);
0524 if (error)
0525 return error;
0526
0527
0528
0529
0530
0531
0532
0533 if (hammer_has_folded_event(hdev)) {
0534 hdev->quirks |= HID_QUIRK_ALWAYS_POLL;
0535 error = hid_hw_open(hdev);
0536 if (error)
0537 return error;
0538
0539 hammer_get_folded_state(hdev);
0540 }
0541
0542 if (hammer_has_backlight_control(hdev)) {
0543 error = hammer_register_leds(hdev);
0544 if (error)
0545 hid_warn(hdev,
0546 "Failed to register keyboard backlight: %d\n",
0547 error);
0548 }
0549
0550 return 0;
0551 }
0552
0553 static void hammer_remove(struct hid_device *hdev)
0554 {
0555 unsigned long flags;
0556
0557 if (hammer_has_folded_event(hdev)) {
0558 hid_hw_close(hdev);
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570 spin_lock_irqsave(&cbas_ec_lock, flags);
0571 if (cbas_ec.input && cbas_ec.base_present) {
0572 input_report_switch(cbas_ec.input, SW_TABLET_MODE, 1);
0573 input_sync(cbas_ec.input);
0574 }
0575 cbas_ec.base_present = false;
0576 spin_unlock_irqrestore(&cbas_ec_lock, flags);
0577 }
0578
0579
0580 }
0581
0582 static const struct hid_device_id hammer_devices[] = {
0583 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
0584 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_DON) },
0585 { HID_DEVICE(BUS_USB, HID_GROUP_VIVALDI,
0586 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_EEL) },
0587 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
0588 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) },
0589 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
0590 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) },
0591 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
0592 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) },
0593 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
0594 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MOONBALL) },
0595 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
0596 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) },
0597 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
0598 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WAND) },
0599 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
0600 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WHISKERS) },
0601 { }
0602 };
0603 MODULE_DEVICE_TABLE(hid, hammer_devices);
0604
0605 static struct hid_driver hammer_driver = {
0606 .name = "hammer",
0607 .id_table = hammer_devices,
0608 .probe = hammer_probe,
0609 .remove = hammer_remove,
0610 .feature_mapping = vivaldi_feature_mapping,
0611 .input_configured = vivaldi_input_configured,
0612 .input_mapping = hammer_input_mapping,
0613 .event = hammer_event,
0614 };
0615
0616 static int __init hammer_init(void)
0617 {
0618 int error;
0619
0620 error = platform_driver_register(&cbas_ec_driver);
0621 if (error)
0622 return error;
0623
0624 error = hid_register_driver(&hammer_driver);
0625 if (error) {
0626 platform_driver_unregister(&cbas_ec_driver);
0627 return error;
0628 }
0629
0630 return 0;
0631 }
0632 module_init(hammer_init);
0633
0634 static void __exit hammer_exit(void)
0635 {
0636 hid_unregister_driver(&hammer_driver);
0637 platform_driver_unregister(&cbas_ec_driver);
0638 }
0639 module_exit(hammer_exit);
0640
0641 MODULE_LICENSE("GPL");