1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * DMI based code to deal with broken DSDTs on X86 tablets which ship with 4 * Android as (part of) the factory image. The factory kernels shipped on these 5 * devices typically have a bunch of things hardcoded, rather than specified 6 * in their DSDT. 7 * 8 * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com> 9 */ 10 11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 12 13 #include <linux/acpi.h> 14 #include <linux/dmi.h> 15 #include <linux/gpio/consumer.h> 16 #include <linux/gpio/machine.h> 17 #include <linux/irq.h> 18 #include <linux/module.h> 19 #include <linux/platform_device.h> 20 #include <linux/serdev.h> 21 #include <linux/string.h> 22 23 #include "x86-android-tablets.h" 24 25 static struct platform_device *x86_android_tablet_device; 26 27 /* 28 * This helper allows getting a gpio_desc *before* the actual device consuming 29 * the GPIO has been instantiated. This function _must_ only be used to handle 30 * this special case such as e.g. : 31 * 32 * 1. Getting an IRQ from a GPIO for i2c_board_info.irq which is passed to 33 * i2c_client_new() to instantiate i2c_client-s; or 34 * 2. Calling desc_to_gpio() to get an old style GPIO number for gpio_keys 35 * platform_data which still uses old style GPIO numbers. 36 * 37 * Since the consuming device has not been instatiated yet a dynamic lookup 38 * is generated using the special x86_android_tablet dev for dev_id. 39 * 40 * For normal GPIO lookups a standard static gpiod_lookup_table _must_ be used. 41 */ 42 int x86_android_tablet_get_gpiod(const char *chip, int pin, const char *con_id, 43 bool active_low, enum gpiod_flags dflags, 44 struct gpio_desc **desc) 45 { 46 struct gpiod_lookup_table *lookup; 47 struct gpio_desc *gpiod; 48 49 lookup = kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); 50 if (!lookup) 51 return -ENOMEM; 52 53 lookup->dev_id = KBUILD_MODNAME; 54 lookup->table[0].key = chip; 55 lookup->table[0].chip_hwnum = pin; 56 lookup->table[0].con_id = con_id; 57 lookup->table[0].flags = active_low ? GPIO_ACTIVE_LOW : GPIO_ACTIVE_HIGH; 58 59 gpiod_add_lookup_table(lookup); 60 gpiod = devm_gpiod_get(&x86_android_tablet_device->dev, con_id, dflags); 61 gpiod_remove_lookup_table(lookup); 62 kfree(lookup); 63 64 if (IS_ERR(gpiod)) { 65 pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), chip, pin); 66 return PTR_ERR(gpiod); 67 } 68 69 if (desc) 70 *desc = gpiod; 71 72 return 0; 73 } 74 75 int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data) 76 { 77 struct irq_fwspec fwspec = { }; 78 struct irq_domain *domain; 79 struct acpi_device *adev; 80 struct gpio_desc *gpiod; 81 unsigned int irq_type; 82 acpi_handle handle; 83 acpi_status status; 84 int irq, ret; 85 86 switch (data->type) { 87 case X86_ACPI_IRQ_TYPE_APIC: 88 /* 89 * The DSDT may already reference the GSI in a device skipped by 90 * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI 91 * to avoid EBUSY errors in this case. 92 */ 93 acpi_unregister_gsi(data->index); 94 irq = acpi_register_gsi(NULL, data->index, data->trigger, data->polarity); 95 if (irq < 0) 96 pr_err("error %d getting APIC IRQ %d\n", irq, data->index); 97 98 return irq; 99 case X86_ACPI_IRQ_TYPE_GPIOINT: 100 /* Like acpi_dev_gpio_irq_get(), but without parsing ACPI resources */ 101 ret = x86_android_tablet_get_gpiod(data->chip, data->index, data->con_id, 102 false, GPIOD_ASIS, &gpiod); 103 if (ret) 104 return ret; 105 106 irq = gpiod_to_irq(gpiod); 107 if (irq < 0) { 108 pr_err("error %d getting IRQ %s %d\n", irq, data->chip, data->index); 109 return irq; 110 } 111 112 irq_type = acpi_dev_get_irq_type(data->trigger, data->polarity); 113 if (irq_type != IRQ_TYPE_NONE && irq_type != irq_get_trigger_type(irq)) 114 irq_set_irq_type(irq, irq_type); 115 116 return irq; 117 case X86_ACPI_IRQ_TYPE_PMIC: 118 status = acpi_get_handle(NULL, data->chip, &handle); 119 if (ACPI_FAILURE(status)) { 120 pr_err("error could not get %s handle\n", data->chip); 121 return -ENODEV; 122 } 123 124 adev = acpi_fetch_acpi_dev(handle); 125 if (!adev) { 126 pr_err("error could not get %s adev\n", data->chip); 127 return -ENODEV; 128 } 129 130 fwspec.fwnode = acpi_fwnode_handle(adev); 131 domain = irq_find_matching_fwspec(&fwspec, data->domain); 132 if (!domain) { 133 pr_err("error could not find IRQ domain for %s\n", data->chip); 134 return -ENODEV; 135 } 136 137 return irq_create_mapping(domain, data->index); 138 default: 139 return 0; 140 } 141 } 142 143 static int i2c_client_count; 144 static int spi_dev_count; 145 static int pdev_count; 146 static int serdev_count; 147 static struct i2c_client **i2c_clients; 148 static struct spi_device **spi_devs; 149 static struct platform_device **pdevs; 150 static struct serdev_device **serdevs; 151 static struct gpio_keys_button *buttons; 152 static struct gpiod_lookup_table * const *gpiod_lookup_tables; 153 static const struct software_node *bat_swnode; 154 static void (*exit_handler)(void); 155 156 static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info, 157 int idx) 158 { 159 const struct x86_i2c_client_info *client_info = &dev_info->i2c_client_info[idx]; 160 struct i2c_board_info board_info = client_info->board_info; 161 struct i2c_adapter *adap; 162 acpi_handle handle; 163 acpi_status status; 164 165 board_info.irq = x86_acpi_irq_helper_get(&client_info->irq_data); 166 if (board_info.irq < 0) 167 return board_info.irq; 168 169 status = acpi_get_handle(NULL, client_info->adapter_path, &handle); 170 if (ACPI_FAILURE(status)) { 171 pr_err("Error could not get %s handle\n", client_info->adapter_path); 172 return -ENODEV; 173 } 174 175 adap = i2c_acpi_find_adapter_by_handle(handle); 176 if (!adap) { 177 pr_err("error could not get %s adapter\n", client_info->adapter_path); 178 return -ENODEV; 179 } 180 181 i2c_clients[idx] = i2c_new_client_device(adap, &board_info); 182 put_device(&adap->dev); 183 if (IS_ERR(i2c_clients[idx])) 184 return dev_err_probe(&adap->dev, PTR_ERR(i2c_clients[idx]), 185 "creating I2C-client %d\n", idx); 186 187 return 0; 188 } 189 190 static __init int x86_instantiate_spi_dev(const struct x86_dev_info *dev_info, int idx) 191 { 192 const struct x86_spi_dev_info *spi_dev_info = &dev_info->spi_dev_info[idx]; 193 struct spi_board_info board_info = spi_dev_info->board_info; 194 struct spi_controller *controller; 195 struct acpi_device *adev; 196 acpi_handle handle; 197 acpi_status status; 198 199 board_info.irq = x86_acpi_irq_helper_get(&spi_dev_info->irq_data); 200 if (board_info.irq < 0) 201 return board_info.irq; 202 203 status = acpi_get_handle(NULL, spi_dev_info->ctrl_path, &handle); 204 if (ACPI_FAILURE(status)) { 205 pr_err("Error could not get %s handle\n", spi_dev_info->ctrl_path); 206 return -ENODEV; 207 } 208 209 adev = acpi_fetch_acpi_dev(handle); 210 if (!adev) { 211 pr_err("Error could not get adev for %s\n", spi_dev_info->ctrl_path); 212 return -ENODEV; 213 } 214 215 controller = acpi_spi_find_controller_by_adev(adev); 216 if (!controller) { 217 pr_err("Error could not get SPI controller for %s\n", spi_dev_info->ctrl_path); 218 return -ENODEV; 219 } 220 221 spi_devs[idx] = spi_new_device(controller, &board_info); 222 put_device(&controller->dev); 223 if (!spi_devs[idx]) 224 return dev_err_probe(&controller->dev, -ENOMEM, 225 "creating SPI-device %d\n", idx); 226 227 return 0; 228 } 229 230 static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx) 231 { 232 struct acpi_device *ctrl_adev, *serdev_adev; 233 struct serdev_device *serdev; 234 struct device *ctrl_dev; 235 int ret = -ENODEV; 236 237 ctrl_adev = acpi_dev_get_first_match_dev(info->ctrl_hid, info->ctrl_uid, -1); 238 if (!ctrl_adev) { 239 pr_err("error could not get %s/%s ctrl adev\n", 240 info->ctrl_hid, info->ctrl_uid); 241 return -ENODEV; 242 } 243 244 serdev_adev = acpi_dev_get_first_match_dev(info->serdev_hid, NULL, -1); 245 if (!serdev_adev) { 246 pr_err("error could not get %s serdev adev\n", info->serdev_hid); 247 goto put_ctrl_adev; 248 } 249 250 /* get_first_physical_node() returns a weak ref, no need to put() it */ 251 ctrl_dev = acpi_get_first_physical_node(ctrl_adev); 252 if (!ctrl_dev) { 253 pr_err("error could not get %s/%s ctrl physical dev\n", 254 info->ctrl_hid, info->ctrl_uid); 255 goto put_serdev_adev; 256 } 257 258 /* ctrl_dev now points to the controller's parent, get the controller */ 259 ctrl_dev = device_find_child_by_name(ctrl_dev, info->ctrl_devname); 260 if (!ctrl_dev) { 261 pr_err("error could not get %s/%s %s ctrl dev\n", 262 info->ctrl_hid, info->ctrl_uid, info->ctrl_devname); 263 goto put_serdev_adev; 264 } 265 266 serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev)); 267 if (!serdev) { 268 ret = -ENOMEM; 269 goto put_serdev_adev; 270 } 271 272 ACPI_COMPANION_SET(&serdev->dev, serdev_adev); 273 acpi_device_set_enumerated(serdev_adev); 274 275 ret = serdev_device_add(serdev); 276 if (ret) { 277 dev_err(&serdev->dev, "error %d adding serdev\n", ret); 278 serdev_device_put(serdev); 279 goto put_serdev_adev; 280 } 281 282 serdevs[idx] = serdev; 283 284 put_serdev_adev: 285 acpi_dev_put(serdev_adev); 286 put_ctrl_adev: 287 acpi_dev_put(ctrl_adev); 288 return ret; 289 } 290 291 static void x86_android_tablet_remove(struct platform_device *pdev) 292 { 293 int i; 294 295 for (i = 0; i < serdev_count; i++) { 296 if (serdevs[i]) 297 serdev_device_remove(serdevs[i]); 298 } 299 300 kfree(serdevs); 301 302 for (i = 0; i < pdev_count; i++) 303 platform_device_unregister(pdevs[i]); 304 305 kfree(pdevs); 306 kfree(buttons); 307 308 for (i = 0; i < spi_dev_count; i++) 309 spi_unregister_device(spi_devs[i]); 310 311 kfree(spi_devs); 312 313 for (i = 0; i < i2c_client_count; i++) 314 i2c_unregister_device(i2c_clients[i]); 315 316 kfree(i2c_clients); 317 318 if (exit_handler) 319 exit_handler(); 320 321 for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++) 322 gpiod_remove_lookup_table(gpiod_lookup_tables[i]); 323 324 software_node_unregister(bat_swnode); 325 } 326 327 static __init int x86_android_tablet_probe(struct platform_device *pdev) 328 { 329 const struct x86_dev_info *dev_info; 330 const struct dmi_system_id *id; 331 int i, ret = 0; 332 333 id = dmi_first_match(x86_android_tablet_ids); 334 if (!id) 335 return -ENODEV; 336 337 dev_info = id->driver_data; 338 /* Allow x86_android_tablet_device use before probe() exits */ 339 x86_android_tablet_device = pdev; 340 341 /* 342 * Since this runs from module_init() it cannot use -EPROBE_DEFER, 343 * instead pre-load any modules which are listed as requirements. 344 */ 345 for (i = 0; dev_info->modules && dev_info->modules[i]; i++) 346 request_module(dev_info->modules[i]); 347 348 bat_swnode = dev_info->bat_swnode; 349 if (bat_swnode) { 350 ret = software_node_register(bat_swnode); 351 if (ret) 352 return ret; 353 } 354 355 gpiod_lookup_tables = dev_info->gpiod_lookup_tables; 356 for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++) 357 gpiod_add_lookup_table(gpiod_lookup_tables[i]); 358 359 if (dev_info->init) { 360 ret = dev_info->init(); 361 if (ret < 0) { 362 x86_android_tablet_remove(pdev); 363 return ret; 364 } 365 exit_handler = dev_info->exit; 366 } 367 368 i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL); 369 if (!i2c_clients) { 370 x86_android_tablet_remove(pdev); 371 return -ENOMEM; 372 } 373 374 i2c_client_count = dev_info->i2c_client_count; 375 for (i = 0; i < i2c_client_count; i++) { 376 ret = x86_instantiate_i2c_client(dev_info, i); 377 if (ret < 0) { 378 x86_android_tablet_remove(pdev); 379 return ret; 380 } 381 } 382 383 spi_devs = kcalloc(dev_info->spi_dev_count, sizeof(*spi_devs), GFP_KERNEL); 384 if (!spi_devs) { 385 x86_android_tablet_remove(pdev); 386 return -ENOMEM; 387 } 388 389 spi_dev_count = dev_info->spi_dev_count; 390 for (i = 0; i < spi_dev_count; i++) { 391 ret = x86_instantiate_spi_dev(dev_info, i); 392 if (ret < 0) { 393 x86_android_tablet_remove(pdev); 394 return ret; 395 } 396 } 397 398 /* + 1 to make space for (optional) gpio_keys_button pdev */ 399 pdevs = kcalloc(dev_info->pdev_count + 1, sizeof(*pdevs), GFP_KERNEL); 400 if (!pdevs) { 401 x86_android_tablet_remove(pdev); 402 return -ENOMEM; 403 } 404 405 pdev_count = dev_info->pdev_count; 406 for (i = 0; i < pdev_count; i++) { 407 pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]); 408 if (IS_ERR(pdevs[i])) { 409 x86_android_tablet_remove(pdev); 410 return PTR_ERR(pdevs[i]); 411 } 412 } 413 414 serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL); 415 if (!serdevs) { 416 x86_android_tablet_remove(pdev); 417 return -ENOMEM; 418 } 419 420 serdev_count = dev_info->serdev_count; 421 for (i = 0; i < serdev_count; i++) { 422 ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i); 423 if (ret < 0) { 424 x86_android_tablet_remove(pdev); 425 return ret; 426 } 427 } 428 429 if (dev_info->gpio_button_count) { 430 struct gpio_keys_platform_data pdata = { }; 431 struct gpio_desc *gpiod; 432 433 buttons = kcalloc(dev_info->gpio_button_count, sizeof(*buttons), GFP_KERNEL); 434 if (!buttons) { 435 x86_android_tablet_remove(pdev); 436 return -ENOMEM; 437 } 438 439 for (i = 0; i < dev_info->gpio_button_count; i++) { 440 ret = x86_android_tablet_get_gpiod(dev_info->gpio_button[i].chip, 441 dev_info->gpio_button[i].pin, 442 dev_info->gpio_button[i].button.desc, 443 false, GPIOD_IN, &gpiod); 444 if (ret < 0) { 445 x86_android_tablet_remove(pdev); 446 return ret; 447 } 448 449 buttons[i] = dev_info->gpio_button[i].button; 450 buttons[i].gpio = desc_to_gpio(gpiod); 451 /* Release gpiod so that gpio-keys can request it */ 452 devm_gpiod_put(&x86_android_tablet_device->dev, gpiod); 453 } 454 455 pdata.buttons = buttons; 456 pdata.nbuttons = dev_info->gpio_button_count; 457 458 pdevs[pdev_count] = platform_device_register_data(&pdev->dev, "gpio-keys", 459 PLATFORM_DEVID_AUTO, 460 &pdata, sizeof(pdata)); 461 if (IS_ERR(pdevs[pdev_count])) { 462 x86_android_tablet_remove(pdev); 463 return PTR_ERR(pdevs[pdev_count]); 464 } 465 pdev_count++; 466 } 467 468 return 0; 469 } 470 471 static struct platform_driver x86_android_tablet_driver = { 472 .driver = { 473 .name = KBUILD_MODNAME, 474 }, 475 .remove_new = x86_android_tablet_remove, 476 }; 477 478 static int __init x86_android_tablet_init(void) 479 { 480 x86_android_tablet_device = platform_create_bundle(&x86_android_tablet_driver, 481 x86_android_tablet_probe, 482 NULL, 0, NULL, 0); 483 484 return PTR_ERR_OR_ZERO(x86_android_tablet_device); 485 } 486 module_init(x86_android_tablet_init); 487 488 static void __exit x86_android_tablet_exit(void) 489 { 490 platform_device_unregister(x86_android_tablet_device); 491 platform_driver_unregister(&x86_android_tablet_driver); 492 } 493 module_exit(x86_android_tablet_exit); 494 495 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 496 MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver"); 497 MODULE_LICENSE("GPL"); 498