0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/input.h>
0011 #include <linux/init.h>
0012 #include <linux/irq.h>
0013 #include <linux/kernel.h>
0014 #include <linux/acpi.h>
0015 #include <linux/dmi.h>
0016 #include <linux/gpio/consumer.h>
0017 #include <linux/gpio_keys.h>
0018 #include <linux/gpio.h>
0019 #include <linux/platform_device.h>
0020
0021 struct soc_button_info {
0022 const char *name;
0023 int acpi_index;
0024 unsigned int event_type;
0025 unsigned int event_code;
0026 bool autorepeat;
0027 bool wakeup;
0028 bool active_low;
0029 };
0030
0031 struct soc_device_data {
0032 const struct soc_button_info *button_info;
0033 int (*check)(struct device *dev);
0034 };
0035
0036
0037
0038
0039
0040
0041 #define BUTTON_TYPES 2
0042
0043 struct soc_button_data {
0044 struct platform_device *children[BUTTON_TYPES];
0045 };
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 static const struct dmi_system_id dmi_use_low_level_irq[] = {
0063 {
0064
0065
0066
0067
0068
0069
0070
0071 .matches = {
0072 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0073 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
0074 },
0075 },
0076 {
0077
0078
0079
0080
0081 .matches = {
0082 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0083 DMI_MATCH(DMI_PRODUCT_NAME, "One S1003"),
0084 },
0085 },
0086 {
0087
0088
0089
0090
0091 .matches = {
0092 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0093 DMI_MATCH(DMI_PRODUCT_NAME, "60073"),
0094 DMI_MATCH(DMI_PRODUCT_VERSION, "1051"),
0095 },
0096 },
0097 {}
0098 };
0099
0100
0101
0102
0103 static int soc_button_lookup_gpio(struct device *dev, int acpi_index,
0104 int *gpio_ret, int *irq_ret)
0105 {
0106 struct gpio_desc *desc;
0107
0108 desc = gpiod_get_index(dev, NULL, acpi_index, GPIOD_ASIS);
0109 if (IS_ERR(desc))
0110 return PTR_ERR(desc);
0111
0112 *gpio_ret = desc_to_gpio(desc);
0113 *irq_ret = gpiod_to_irq(desc);
0114
0115 gpiod_put(desc);
0116
0117 return 0;
0118 }
0119
0120 static struct platform_device *
0121 soc_button_device_create(struct platform_device *pdev,
0122 const struct soc_button_info *button_info,
0123 bool autorepeat)
0124 {
0125 const struct soc_button_info *info;
0126 struct platform_device *pd;
0127 struct gpio_keys_button *gpio_keys;
0128 struct gpio_keys_platform_data *gpio_keys_pdata;
0129 int error, gpio, irq;
0130 int n_buttons = 0;
0131
0132 for (info = button_info; info->name; info++)
0133 if (info->autorepeat == autorepeat)
0134 n_buttons++;
0135
0136 gpio_keys_pdata = devm_kzalloc(&pdev->dev,
0137 sizeof(*gpio_keys_pdata) +
0138 sizeof(*gpio_keys) * n_buttons,
0139 GFP_KERNEL);
0140 if (!gpio_keys_pdata)
0141 return ERR_PTR(-ENOMEM);
0142
0143 gpio_keys = (void *)(gpio_keys_pdata + 1);
0144 n_buttons = 0;
0145
0146 for (info = button_info; info->name; info++) {
0147 if (info->autorepeat != autorepeat)
0148 continue;
0149
0150 error = soc_button_lookup_gpio(&pdev->dev, info->acpi_index, &gpio, &irq);
0151 if (error || irq < 0) {
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 continue;
0164 }
0165
0166
0167 if (!autorepeat && dmi_check_system(dmi_use_low_level_irq)) {
0168 irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
0169 gpio_keys[n_buttons].irq = irq;
0170 gpio_keys[n_buttons].gpio = -ENOENT;
0171 } else {
0172 gpio_keys[n_buttons].gpio = gpio;
0173 }
0174
0175 gpio_keys[n_buttons].type = info->event_type;
0176 gpio_keys[n_buttons].code = info->event_code;
0177 gpio_keys[n_buttons].active_low = info->active_low;
0178 gpio_keys[n_buttons].desc = info->name;
0179 gpio_keys[n_buttons].wakeup = info->wakeup;
0180
0181 gpio_keys[n_buttons].debounce_interval = 50;
0182 n_buttons++;
0183 }
0184
0185 if (n_buttons == 0) {
0186 error = -ENODEV;
0187 goto err_free_mem;
0188 }
0189
0190 gpio_keys_pdata->buttons = gpio_keys;
0191 gpio_keys_pdata->nbuttons = n_buttons;
0192 gpio_keys_pdata->rep = autorepeat;
0193
0194 pd = platform_device_register_resndata(&pdev->dev, "gpio-keys",
0195 PLATFORM_DEVID_AUTO, NULL, 0,
0196 gpio_keys_pdata,
0197 sizeof(*gpio_keys_pdata));
0198 error = PTR_ERR_OR_ZERO(pd);
0199 if (error) {
0200 dev_err(&pdev->dev,
0201 "failed registering gpio-keys: %d\n", error);
0202 goto err_free_mem;
0203 }
0204
0205 return pd;
0206
0207 err_free_mem:
0208 devm_kfree(&pdev->dev, gpio_keys_pdata);
0209 return ERR_PTR(error);
0210 }
0211
0212 static int soc_button_get_acpi_object_int(const union acpi_object *obj)
0213 {
0214 if (obj->type != ACPI_TYPE_INTEGER)
0215 return -1;
0216
0217 return obj->integer.value;
0218 }
0219
0220
0221 static int soc_button_parse_btn_desc(struct device *dev,
0222 const union acpi_object *desc,
0223 int collection_uid,
0224 struct soc_button_info *info)
0225 {
0226 int upage, usage;
0227
0228 if (desc->type != ACPI_TYPE_PACKAGE ||
0229 desc->package.count != 5 ||
0230
0231 soc_button_get_acpi_object_int(&desc->package.elements[0]) != 1 ||
0232
0233 soc_button_get_acpi_object_int(&desc->package.elements[2]) !=
0234 collection_uid) {
0235 dev_err(dev, "Invalid ACPI Button Descriptor\n");
0236 return -ENODEV;
0237 }
0238
0239 info->event_type = EV_KEY;
0240 info->active_low = true;
0241 info->acpi_index =
0242 soc_button_get_acpi_object_int(&desc->package.elements[1]);
0243 upage = soc_button_get_acpi_object_int(&desc->package.elements[3]);
0244 usage = soc_button_get_acpi_object_int(&desc->package.elements[4]);
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 if (upage == 0x01 && usage == 0x81) {
0257 info->name = "power";
0258 info->event_code = KEY_POWER;
0259 info->wakeup = true;
0260 } else if (upage == 0x01 && usage == 0xca) {
0261 info->name = "rotation lock switch";
0262 info->event_type = EV_SW;
0263 info->event_code = SW_ROTATE_LOCK;
0264 } else if (upage == 0x07 && usage == 0xe3) {
0265 info->name = "home";
0266 info->event_code = KEY_LEFTMETA;
0267 info->wakeup = true;
0268 } else if (upage == 0x0c && usage == 0xe9) {
0269 info->name = "volume_up";
0270 info->event_code = KEY_VOLUMEUP;
0271 info->autorepeat = true;
0272 } else if (upage == 0x0c && usage == 0xea) {
0273 info->name = "volume_down";
0274 info->event_code = KEY_VOLUMEDOWN;
0275 info->autorepeat = true;
0276 } else {
0277 dev_warn(dev, "Unknown button index %d upage %02x usage %02x, ignoring\n",
0278 info->acpi_index, upage, usage);
0279 info->name = "unknown";
0280 info->event_code = KEY_RESERVED;
0281 }
0282
0283 return 0;
0284 }
0285
0286
0287 static const u8 btns_desc_uuid[16] = {
0288 0x25, 0xd6, 0x6b, 0xfa, 0xe8, 0x9c, 0x0d, 0x47,
0289 0xa2, 0xc7, 0xb3, 0xca, 0x36, 0xc4, 0x28, 0x2e
0290 };
0291
0292
0293 static struct soc_button_info *soc_button_get_button_info(struct device *dev)
0294 {
0295 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
0296 const union acpi_object *desc, *el0, *uuid, *btns_desc = NULL;
0297 struct soc_button_info *button_info;
0298 acpi_status status;
0299 int i, btn, collection_uid = -1;
0300
0301 status = acpi_evaluate_object_typed(ACPI_HANDLE(dev), "_DSD", NULL,
0302 &buf, ACPI_TYPE_PACKAGE);
0303 if (ACPI_FAILURE(status)) {
0304 dev_err(dev, "ACPI _DSD object not found\n");
0305 return ERR_PTR(-ENODEV);
0306 }
0307
0308
0309 desc = buf.pointer;
0310 for (i = 0; (i + 1) < desc->package.count; i += 2) {
0311 uuid = &desc->package.elements[i];
0312
0313 if (uuid->type != ACPI_TYPE_BUFFER ||
0314 uuid->buffer.length != 16 ||
0315 desc->package.elements[i + 1].type != ACPI_TYPE_PACKAGE) {
0316 break;
0317 }
0318
0319 if (memcmp(uuid->buffer.pointer, btns_desc_uuid, 16) == 0) {
0320 btns_desc = &desc->package.elements[i + 1];
0321 break;
0322 }
0323 }
0324
0325 if (!btns_desc) {
0326 dev_err(dev, "ACPI Button Descriptors not found\n");
0327 button_info = ERR_PTR(-ENODEV);
0328 goto out;
0329 }
0330
0331
0332 el0 = &btns_desc->package.elements[0];
0333 if (el0->type == ACPI_TYPE_PACKAGE &&
0334 el0->package.count == 5 &&
0335
0336 soc_button_get_acpi_object_int(&el0->package.elements[0]) == 0 &&
0337
0338 soc_button_get_acpi_object_int(&el0->package.elements[2]) == 0) {
0339 collection_uid = soc_button_get_acpi_object_int(
0340 &el0->package.elements[1]);
0341 }
0342 if (collection_uid == -1) {
0343 dev_err(dev, "Invalid Button Collection Descriptor\n");
0344 button_info = ERR_PTR(-ENODEV);
0345 goto out;
0346 }
0347
0348
0349 button_info = devm_kcalloc(dev, btns_desc->package.count,
0350 sizeof(*button_info), GFP_KERNEL);
0351 if (!button_info) {
0352 button_info = ERR_PTR(-ENOMEM);
0353 goto out;
0354 }
0355
0356
0357 for (i = 1, btn = 0; i < btns_desc->package.count; i++, btn++) {
0358 if (soc_button_parse_btn_desc(dev,
0359 &btns_desc->package.elements[i],
0360 collection_uid,
0361 &button_info[btn])) {
0362 button_info = ERR_PTR(-ENODEV);
0363 goto out;
0364 }
0365 }
0366
0367 out:
0368 kfree(buf.pointer);
0369 return button_info;
0370 }
0371
0372 static int soc_button_remove(struct platform_device *pdev)
0373 {
0374 struct soc_button_data *priv = platform_get_drvdata(pdev);
0375
0376 int i;
0377
0378 for (i = 0; i < BUTTON_TYPES; i++)
0379 if (priv->children[i])
0380 platform_device_unregister(priv->children[i]);
0381
0382 return 0;
0383 }
0384
0385 static int soc_button_probe(struct platform_device *pdev)
0386 {
0387 struct device *dev = &pdev->dev;
0388 const struct soc_device_data *device_data;
0389 const struct soc_button_info *button_info;
0390 struct soc_button_data *priv;
0391 struct platform_device *pd;
0392 int i;
0393 int error;
0394
0395 device_data = acpi_device_get_match_data(dev);
0396 if (device_data && device_data->check) {
0397 error = device_data->check(dev);
0398 if (error)
0399 return error;
0400 }
0401
0402 if (device_data && device_data->button_info) {
0403 button_info = device_data->button_info;
0404 } else {
0405 button_info = soc_button_get_button_info(dev);
0406 if (IS_ERR(button_info))
0407 return PTR_ERR(button_info);
0408 }
0409
0410 error = gpiod_count(dev, NULL);
0411 if (error < 0) {
0412 dev_dbg(dev, "no GPIO attached, ignoring...\n");
0413 return -ENODEV;
0414 }
0415
0416 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0417 if (!priv)
0418 return -ENOMEM;
0419
0420 platform_set_drvdata(pdev, priv);
0421
0422 for (i = 0; i < BUTTON_TYPES; i++) {
0423 pd = soc_button_device_create(pdev, button_info, i == 0);
0424 if (IS_ERR(pd)) {
0425 error = PTR_ERR(pd);
0426 if (error != -ENODEV) {
0427 soc_button_remove(pdev);
0428 return error;
0429 }
0430 continue;
0431 }
0432
0433 priv->children[i] = pd;
0434 }
0435
0436 if (!priv->children[0] && !priv->children[1])
0437 return -ENODEV;
0438
0439 if (!device_data || !device_data->button_info)
0440 devm_kfree(dev, button_info);
0441
0442 return 0;
0443 }
0444
0445
0446
0447
0448
0449
0450 static const struct soc_button_info soc_button_PNP0C40[] = {
0451 { "power", 0, EV_KEY, KEY_POWER, false, true, true },
0452 { "home", 1, EV_KEY, KEY_LEFTMETA, false, true, true },
0453 { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false, true },
0454 { "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false, true },
0455 { "rotation_lock", 4, EV_KEY, KEY_ROTATE_LOCK_TOGGLE, false, false, true },
0456 { }
0457 };
0458
0459 static const struct soc_device_data soc_device_PNP0C40 = {
0460 .button_info = soc_button_PNP0C40,
0461 };
0462
0463 static const struct soc_button_info soc_button_INT33D3[] = {
0464 { "tablet_mode", 0, EV_SW, SW_TABLET_MODE, false, false, false },
0465 { }
0466 };
0467
0468 static const struct soc_device_data soc_device_INT33D3 = {
0469 .button_info = soc_button_INT33D3,
0470 };
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481 static const struct soc_button_info soc_button_MSHW0028[] = {
0482 { "power", 0, EV_KEY, KEY_POWER, false, true, true },
0483 { "home", 1, EV_KEY, KEY_LEFTMETA, false, true, false },
0484 { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false, true },
0485 { "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false, true },
0486 { }
0487 };
0488
0489 static const struct soc_device_data soc_device_MSHW0028 = {
0490 .button_info = soc_button_MSHW0028,
0491 };
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501 #define MSHW0040_DSM_REVISION 0x01
0502 #define MSHW0040_DSM_GET_OMPR 0x02
0503 static const guid_t MSHW0040_DSM_UUID =
0504 GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
0505 0x49, 0x80, 0x35);
0506
0507 static int soc_device_check_MSHW0040(struct device *dev)
0508 {
0509 acpi_handle handle = ACPI_HANDLE(dev);
0510 union acpi_object *result;
0511 u64 oem_platform_rev = 0;
0512
0513
0514 result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
0515 MSHW0040_DSM_REVISION,
0516 MSHW0040_DSM_GET_OMPR, NULL,
0517 ACPI_TYPE_INTEGER);
0518
0519 if (result) {
0520 oem_platform_rev = result->integer.value;
0521 ACPI_FREE(result);
0522 }
0523
0524
0525
0526
0527
0528
0529 if (oem_platform_rev == 0)
0530 return -ENODEV;
0531
0532 dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev);
0533
0534 return 0;
0535 }
0536
0537
0538
0539
0540
0541 static const struct soc_button_info soc_button_MSHW0040[] = {
0542 { "power", 0, EV_KEY, KEY_POWER, false, true, true },
0543 { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false, true },
0544 { "volume_down", 4, EV_KEY, KEY_VOLUMEDOWN, true, false, true },
0545 { }
0546 };
0547
0548 static const struct soc_device_data soc_device_MSHW0040 = {
0549 .button_info = soc_button_MSHW0040,
0550 .check = soc_device_check_MSHW0040,
0551 };
0552
0553 static const struct acpi_device_id soc_button_acpi_match[] = {
0554 { "PNP0C40", (unsigned long)&soc_device_PNP0C40 },
0555 { "INT33D3", (unsigned long)&soc_device_INT33D3 },
0556 { "ID9001", (unsigned long)&soc_device_INT33D3 },
0557 { "ACPI0011", 0 },
0558
0559
0560 { "MSHW0028", (unsigned long)&soc_device_MSHW0028 },
0561 { "MSHW0040", (unsigned long)&soc_device_MSHW0040 },
0562
0563 { }
0564 };
0565
0566 MODULE_DEVICE_TABLE(acpi, soc_button_acpi_match);
0567
0568 static struct platform_driver soc_button_driver = {
0569 .probe = soc_button_probe,
0570 .remove = soc_button_remove,
0571 .driver = {
0572 .name = KBUILD_MODNAME,
0573 .acpi_match_table = ACPI_PTR(soc_button_acpi_match),
0574 },
0575 };
0576 module_platform_driver(soc_button_driver);
0577
0578 MODULE_LICENSE("GPL");