Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1// SPDX-License-Identifier: GPL-2.0+
   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-2022 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/efi.h>
  16#include <linux/gpio_keys.h>
  17#include <linux/gpio/consumer.h>
  18#include <linux/gpio/driver.h>
  19#include <linux/gpio/machine.h>
  20#include <linux/i2c.h>
  21#include <linux/input.h>
  22#include <linux/irq.h>
  23#include <linux/irqdomain.h>
  24#include <linux/module.h>
  25#include <linux/mod_devicetable.h>
  26#include <linux/pinctrl/consumer.h>
  27#include <linux/pinctrl/machine.h>
  28#include <linux/platform_data/lp855x.h>
  29#include <linux/platform_device.h>
  30#include <linux/power/bq24190_charger.h>
  31#include <linux/reboot.h>
  32#include <linux/rmi.h>
  33#include <linux/serdev.h>
  34#include <linux/spi/spi.h>
  35#include <linux/string.h>
  36/* For gpio_get_desc() which is EXPORT_SYMBOL_GPL() */
  37#include "../../gpio/gpiolib.h"
  38#include "../../gpio/gpiolib-acpi.h"
  39
  40/*
  41 * Helper code to get Linux IRQ numbers given a description of the IRQ source
  42 * (either IOAPIC index, or GPIO chip name + pin-number).
  43 */
  44enum x86_acpi_irq_type {
  45	X86_ACPI_IRQ_TYPE_NONE,
  46	X86_ACPI_IRQ_TYPE_APIC,
  47	X86_ACPI_IRQ_TYPE_GPIOINT,
  48	X86_ACPI_IRQ_TYPE_PMIC,
  49};
  50
  51struct x86_acpi_irq_data {
  52	char *chip;   /* GPIO chip label (GPIOINT) or PMIC ACPI path (PMIC) */
  53	enum x86_acpi_irq_type type;
  54	enum irq_domain_bus_token domain;
  55	int index;
  56	int trigger;  /* ACPI_EDGE_SENSITIVE / ACPI_LEVEL_SENSITIVE */
  57	int polarity; /* ACPI_ACTIVE_HIGH / ACPI_ACTIVE_LOW / ACPI_ACTIVE_BOTH */
  58};
  59
  60static int gpiochip_find_match_label(struct gpio_chip *gc, void *data)
  61{
  62	return gc->label && !strcmp(gc->label, data);
  63}
  64
  65static int x86_android_tablet_get_gpiod(char *label, int pin, struct gpio_desc **desc)
  66{
  67	struct gpio_desc *gpiod;
  68	struct gpio_chip *chip;
  69
  70	chip = gpiochip_find(label, gpiochip_find_match_label);
  71	if (!chip) {
  72		pr_err("error cannot find GPIO chip %s\n", label);
  73		return -ENODEV;
  74	}
  75
  76	gpiod = gpiochip_get_desc(chip, pin);
  77	if (IS_ERR(gpiod)) {
  78		pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), label, pin);
  79		return PTR_ERR(gpiod);
  80	}
  81
  82	*desc = gpiod;
  83	return 0;
  84}
  85
  86static int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data)
  87{
  88	struct irq_fwspec fwspec = { };
  89	struct irq_domain *domain;
  90	struct acpi_device *adev;
  91	struct gpio_desc *gpiod;
  92	unsigned int irq_type;
  93	acpi_handle handle;
  94	acpi_status status;
  95	int irq, ret;
  96
  97	switch (data->type) {
  98	case X86_ACPI_IRQ_TYPE_APIC:
  99		/*
 100		 * The DSDT may already reference the GSI in a device skipped by
 101		 * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI
 102		 * to avoid EBUSY errors in this case.
 103		 */
 104		acpi_unregister_gsi(data->index);
 105		irq = acpi_register_gsi(NULL, data->index, data->trigger, data->polarity);
 106		if (irq < 0)
 107			pr_err("error %d getting APIC IRQ %d\n", irq, data->index);
 108
 109		return irq;
 110	case X86_ACPI_IRQ_TYPE_GPIOINT:
 111		/* Like acpi_dev_gpio_irq_get(), but without parsing ACPI resources */
 112		ret = x86_android_tablet_get_gpiod(data->chip, data->index, &gpiod);
 113		if (ret)
 114			return ret;
 115
 116		irq = gpiod_to_irq(gpiod);
 117		if (irq < 0) {
 118			pr_err("error %d getting IRQ %s %d\n", irq, data->chip, data->index);
 119			return irq;
 120		}
 121
 122		irq_type = acpi_dev_get_irq_type(data->trigger, data->polarity);
 123		if (irq_type != IRQ_TYPE_NONE && irq_type != irq_get_trigger_type(irq))
 124			irq_set_irq_type(irq, irq_type);
 125
 126		return irq;
 127	case X86_ACPI_IRQ_TYPE_PMIC:
 128		status = acpi_get_handle(NULL, data->chip, &handle);
 129		if (ACPI_FAILURE(status)) {
 130			pr_err("error could not get %s handle\n", data->chip);
 131			return -ENODEV;
 132		}
 133
 134		adev = acpi_fetch_acpi_dev(handle);
 135		if (!adev) {
 136			pr_err("error could not get %s adev\n", data->chip);
 137			return -ENODEV;
 138		}
 139
 140		fwspec.fwnode = acpi_fwnode_handle(adev);
 141		domain = irq_find_matching_fwspec(&fwspec, data->domain);
 142		if (!domain) {
 143			pr_err("error could not find IRQ domain for %s\n", data->chip);
 144			return -ENODEV;
 145		}
 146
 147		return irq_create_mapping(domain, data->index);
 148	default:
 149		return 0;
 150	}
 151}
 152
 153struct x86_i2c_client_info {
 154	struct i2c_board_info board_info;
 155	char *adapter_path;
 156	struct x86_acpi_irq_data irq_data;
 157};
 158
 159struct x86_serdev_info {
 160	const char *ctrl_hid;
 161	const char *ctrl_uid;
 162	const char *ctrl_devname;
 163	/*
 164	 * ATM the serdev core only supports of or ACPI matching; and sofar all
 165	 * Android x86 tablets DSDTs have usable serdev nodes, but sometimes
 166	 * under the wrong controller. So we just tie the existing serdev ACPI
 167	 * node to the right controller.
 168	 */
 169	const char *serdev_hid;
 170};
 171
 172struct x86_dev_info {
 173	char *invalid_aei_gpiochip;
 174	const char * const *modules;
 175	const struct software_node *bat_swnode;
 176	struct gpiod_lookup_table * const *gpiod_lookup_tables;
 177	const struct x86_i2c_client_info *i2c_client_info;
 178	const struct platform_device_info *pdev_info;
 179	const struct x86_serdev_info *serdev_info;
 180	int i2c_client_count;
 181	int pdev_count;
 182	int serdev_count;
 183	int (*init)(void);
 184	void (*exit)(void);
 185};
 186
 187/* Generic / shared charger / battery settings */
 188static const char * const tusb1211_chg_det_psy[] = { "tusb1211-charger-detect" };
 189static const char * const bq24190_psy[] = { "bq24190-charger" };
 190static const char * const bq25890_psy[] = { "bq25890-charger" };
 191
 192static const struct property_entry fg_bq24190_supply_props[] = {
 193	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
 194	{ }
 195};
 196
 197static const struct software_node fg_bq24190_supply_node = {
 198	.properties = fg_bq24190_supply_props,
 199};
 200
 201static const struct property_entry fg_bq25890_supply_props[] = {
 202	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_psy),
 203	{ }
 204};
 205
 206static const struct software_node fg_bq25890_supply_node = {
 207	.properties = fg_bq25890_supply_props,
 208};
 209
 210/* LiPo HighVoltage (max 4.35V) settings used by most devs with a HV bat. */
 211static const struct property_entry generic_lipo_hv_4v35_battery_props[] = {
 212	PROPERTY_ENTRY_STRING("compatible", "simple-battery"),
 213	PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion"),
 214	PROPERTY_ENTRY_U32("precharge-current-microamp", 256000),
 215	PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000),
 216	PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 1856000),
 217	PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4352000),
 218	PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000),
 219	{ }
 220};
 221
 222static const struct software_node generic_lipo_hv_4v35_battery_node = {
 223	.properties = generic_lipo_hv_4v35_battery_props,
 224};
 225
 226/* For enabling the bq24190 5V boost based on id-pin */
 227static struct regulator_consumer_supply intel_int3496_consumer = {
 228	.supply = "vbus",
 229	.dev_name = "intel-int3496",
 230};
 231
 232static const struct regulator_init_data bq24190_vbus_init_data = {
 233	.constraints = {
 234		.name = "bq24190_vbus",
 235		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
 236	},
 237	.consumer_supplies = &intel_int3496_consumer,
 238	.num_consumer_supplies = 1,
 239};
 240
 241static struct bq24190_platform_data bq24190_pdata = {
 242	.regulator_init_data = &bq24190_vbus_init_data,
 243};
 244
 245static const char * const bq24190_modules[] __initconst = {
 246	"intel_crystal_cove_charger", /* For the bq24190 IRQ */
 247	"bq24190_charger",            /* For the Vbus regulator for intel-int3496 */
 248	NULL
 249};
 250
 251/* Generic pdevs array and gpio-lookups for micro USB ID pin handling */
 252static const struct platform_device_info int3496_pdevs[] __initconst = {
 253	{
 254		/* For micro USB ID pin handling */
 255		.name = "intel-int3496",
 256		.id = PLATFORM_DEVID_NONE,
 257	},
 258};
 259
 260static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = {
 261	.dev_id = "intel-int3496",
 262	.table = {
 263		GPIO_LOOKUP("INT33FC:02", 22, "id", GPIO_ACTIVE_HIGH),
 264		{ }
 265	},
 266};
 267
 268/*
 269 * Advantech MICA-071
 270 * This is a standard Windows tablet, but it has an extra "quick launch" button
 271 * which is not described in the ACPI tables in anyway.
 272 * Use the x86-android-tablets infra to create a gpio-button device for this.
 273 */
 274static struct gpio_keys_button advantech_mica_071_button = {
 275	.code = KEY_PROG1,
 276	/* .gpio gets filled in by advantech_mica_071_init() */
 277	.active_low = true,
 278	.desc = "prog1_key",
 279	.type = EV_KEY,
 280	.wakeup = false,
 281	.debounce_interval = 50,
 282};
 283
 284static const struct gpio_keys_platform_data advantech_mica_071_button_pdata __initconst = {
 285	.buttons = &advantech_mica_071_button,
 286	.nbuttons = 1,
 287	.name = "prog1_key",
 288};
 289
 290static const struct platform_device_info advantech_mica_071_pdevs[] __initconst = {
 291	{
 292		.name = "gpio-keys",
 293		.id = PLATFORM_DEVID_AUTO,
 294		.data = &advantech_mica_071_button_pdata,
 295		.size_data = sizeof(advantech_mica_071_button_pdata),
 296	},
 297};
 298
 299static int __init advantech_mica_071_init(void)
 300{
 301	struct gpio_desc *gpiod;
 302	int ret;
 303
 304	ret = x86_android_tablet_get_gpiod("INT33FC:00", 2, &gpiod);
 305	if (ret < 0)
 306		return ret;
 307	advantech_mica_071_button.gpio = desc_to_gpio(gpiod);
 308
 309	return 0;
 310}
 311
 312static const struct x86_dev_info advantech_mica_071_info __initconst = {
 313	.pdev_info = advantech_mica_071_pdevs,
 314	.pdev_count = ARRAY_SIZE(advantech_mica_071_pdevs),
 315	.init = advantech_mica_071_init,
 316};
 317
 318/* Asus ME176C and TF103C tablets shared data */
 319static struct gpio_keys_button asus_me176c_tf103c_lid = {
 320	.code = SW_LID,
 321	/* .gpio gets filled in by asus_me176c_tf103c_init() */
 322	.active_low = true,
 323	.desc = "lid_sw",
 324	.type = EV_SW,
 325	.wakeup = true,
 326	.debounce_interval = 50,
 327};
 328
 329static const struct gpio_keys_platform_data asus_me176c_tf103c_lid_pdata __initconst = {
 330	.buttons = &asus_me176c_tf103c_lid,
 331	.nbuttons = 1,
 332	.name = "lid_sw",
 333};
 334
 335static const struct platform_device_info asus_me176c_tf103c_pdevs[] __initconst = {
 336	{
 337		.name = "gpio-keys",
 338		.id = PLATFORM_DEVID_AUTO,
 339		.data = &asus_me176c_tf103c_lid_pdata,
 340		.size_data = sizeof(asus_me176c_tf103c_lid_pdata),
 341	},
 342	{
 343		/* For micro USB ID pin handling */
 344		.name = "intel-int3496",
 345		.id = PLATFORM_DEVID_NONE,
 346	},
 347};
 348
 349static int __init asus_me176c_tf103c_init(void)
 350{
 351	struct gpio_desc *gpiod;
 352	int ret;
 353
 354	ret = x86_android_tablet_get_gpiod("INT33FC:02", 12, &gpiod);
 355	if (ret < 0)
 356		return ret;
 357	asus_me176c_tf103c_lid.gpio = desc_to_gpio(gpiod);
 358
 359	return 0;
 360}
 361
 362
 363/* Asus ME176C tablets have an Android factory img with everything hardcoded */
 364static const char * const asus_me176c_accel_mount_matrix[] = {
 365	"-1", "0", "0",
 366	"0", "1", "0",
 367	"0", "0", "1"
 368};
 369
 370static const struct property_entry asus_me176c_accel_props[] = {
 371	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_me176c_accel_mount_matrix),
 372	{ }
 373};
 374
 375static const struct software_node asus_me176c_accel_node = {
 376	.properties = asus_me176c_accel_props,
 377};
 378
 379static const struct property_entry asus_me176c_bq24190_props[] = {
 380	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
 381	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
 382	PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000),
 383	PROPERTY_ENTRY_BOOL("omit-battery-class"),
 384	PROPERTY_ENTRY_BOOL("disable-reset"),
 385	{ }
 386};
 387
 388static const struct software_node asus_me176c_bq24190_node = {
 389	.properties = asus_me176c_bq24190_props,
 390};
 391
 392static const struct property_entry asus_me176c_ug3105_props[] = {
 393	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
 394	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
 395	PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 10000),
 396	{ }
 397};
 398
 399static const struct software_node asus_me176c_ug3105_node = {
 400	.properties = asus_me176c_ug3105_props,
 401};
 402
 403static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = {
 404	{
 405		/* bq24297 battery charger */
 406		.board_info = {
 407			.type = "bq24190",
 408			.addr = 0x6b,
 409			.dev_name = "bq24297",
 410			.swnode = &asus_me176c_bq24190_node,
 411			.platform_data = &bq24190_pdata,
 412		},
 413		.adapter_path = "\\_SB_.I2C1",
 414		.irq_data = {
 415			.type = X86_ACPI_IRQ_TYPE_PMIC,
 416			.chip = "\\_SB_.I2C7.PMIC",
 417			.domain = DOMAIN_BUS_WAKEUP,
 418			.index = 0,
 419		},
 420	}, {
 421		/* ug3105 battery monitor */
 422		.board_info = {
 423			.type = "ug3105",
 424			.addr = 0x70,
 425			.dev_name = "ug3105",
 426			.swnode = &asus_me176c_ug3105_node,
 427		},
 428		.adapter_path = "\\_SB_.I2C1",
 429	}, {
 430		/* ak09911 compass */
 431		.board_info = {
 432			.type = "ak09911",
 433			.addr = 0x0c,
 434			.dev_name = "ak09911",
 435		},
 436		.adapter_path = "\\_SB_.I2C5",
 437	}, {
 438		/* kxtj21009 accel */
 439		.board_info = {
 440			.type = "kxtj21009",
 441			.addr = 0x0f,
 442			.dev_name = "kxtj21009",
 443			.swnode = &asus_me176c_accel_node,
 444		},
 445		.adapter_path = "\\_SB_.I2C5",
 446		.irq_data = {
 447			.type = X86_ACPI_IRQ_TYPE_APIC,
 448			.index = 0x44,
 449			.trigger = ACPI_EDGE_SENSITIVE,
 450			.polarity = ACPI_ACTIVE_LOW,
 451		},
 452	}, {
 453		/* goodix touchscreen */
 454		.board_info = {
 455			.type = "GDIX1001:00",
 456			.addr = 0x14,
 457			.dev_name = "goodix_ts",
 458		},
 459		.adapter_path = "\\_SB_.I2C6",
 460		.irq_data = {
 461			.type = X86_ACPI_IRQ_TYPE_APIC,
 462			.index = 0x45,
 463			.trigger = ACPI_EDGE_SENSITIVE,
 464			.polarity = ACPI_ACTIVE_LOW,
 465		},
 466	},
 467};
 468
 469static const struct x86_serdev_info asus_me176c_serdevs[] __initconst = {
 470	{
 471		.ctrl_hid = "80860F0A",
 472		.ctrl_uid = "2",
 473		.ctrl_devname = "serial0",
 474		.serdev_hid = "BCM2E3A",
 475	},
 476};
 477
 478static struct gpiod_lookup_table asus_me176c_goodix_gpios = {
 479	.dev_id = "i2c-goodix_ts",
 480	.table = {
 481		GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_HIGH),
 482		GPIO_LOOKUP("INT33FC:02", 28, "irq", GPIO_ACTIVE_HIGH),
 483		{ }
 484	},
 485};
 486
 487static struct gpiod_lookup_table * const asus_me176c_gpios[] = {
 488	&int3496_gpo2_pin22_gpios,
 489	&asus_me176c_goodix_gpios,
 490	NULL
 491};
 492
 493static const struct x86_dev_info asus_me176c_info __initconst = {
 494	.i2c_client_info = asus_me176c_i2c_clients,
 495	.i2c_client_count = ARRAY_SIZE(asus_me176c_i2c_clients),
 496	.pdev_info = asus_me176c_tf103c_pdevs,
 497	.pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs),
 498	.serdev_info = asus_me176c_serdevs,
 499	.serdev_count = ARRAY_SIZE(asus_me176c_serdevs),
 500	.gpiod_lookup_tables = asus_me176c_gpios,
 501	.bat_swnode = &generic_lipo_hv_4v35_battery_node,
 502	.modules = bq24190_modules,
 503	.invalid_aei_gpiochip = "INT33FC:02",
 504	.init = asus_me176c_tf103c_init,
 505};
 506
 507/* Asus TF103C tablets have an Android factory img with everything hardcoded */
 508static const char * const asus_tf103c_accel_mount_matrix[] = {
 509	"0", "-1", "0",
 510	"-1", "0", "0",
 511	"0", "0", "1"
 512};
 513
 514static const struct property_entry asus_tf103c_accel_props[] = {
 515	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_tf103c_accel_mount_matrix),
 516	{ }
 517};
 518
 519static const struct software_node asus_tf103c_accel_node = {
 520	.properties = asus_tf103c_accel_props,
 521};
 522
 523static const struct property_entry asus_tf103c_touchscreen_props[] = {
 524	PROPERTY_ENTRY_STRING("compatible", "atmel,atmel_mxt_ts"),
 525	{ }
 526};
 527
 528static const struct software_node asus_tf103c_touchscreen_node = {
 529	.properties = asus_tf103c_touchscreen_props,
 530};
 531
 532static const struct property_entry asus_tf103c_battery_props[] = {
 533	PROPERTY_ENTRY_STRING("compatible", "simple-battery"),
 534	PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion-polymer"),
 535	PROPERTY_ENTRY_U32("precharge-current-microamp", 256000),
 536	PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000),
 537	PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 2048000),
 538	PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4208000),
 539	PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000),
 540	{ }
 541};
 542
 543static const struct software_node asus_tf103c_battery_node = {
 544	.properties = asus_tf103c_battery_props,
 545};
 546
 547static const struct property_entry asus_tf103c_bq24190_props[] = {
 548	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
 549	PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node),
 550	PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000),
 551	PROPERTY_ENTRY_BOOL("omit-battery-class"),
 552	PROPERTY_ENTRY_BOOL("disable-reset"),
 553	{ }
 554};
 555
 556static const struct software_node asus_tf103c_bq24190_node = {
 557	.properties = asus_tf103c_bq24190_props,
 558};
 559
 560static const struct property_entry asus_tf103c_ug3105_props[] = {
 561	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
 562	PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node),
 563	PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 5000),
 564	{ }
 565};
 566
 567static const struct software_node asus_tf103c_ug3105_node = {
 568	.properties = asus_tf103c_ug3105_props,
 569};
 570
 571static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = {
 572	{
 573		/* bq24297 battery charger */
 574		.board_info = {
 575			.type = "bq24190",
 576			.addr = 0x6b,
 577			.dev_name = "bq24297",
 578			.swnode = &asus_tf103c_bq24190_node,
 579			.platform_data = &bq24190_pdata,
 580		},
 581		.adapter_path = "\\_SB_.I2C1",
 582		.irq_data = {
 583			.type = X86_ACPI_IRQ_TYPE_PMIC,
 584			.chip = "\\_SB_.I2C7.PMIC",
 585			.domain = DOMAIN_BUS_WAKEUP,
 586			.index = 0,
 587		},
 588	}, {
 589		/* ug3105 battery monitor */
 590		.board_info = {
 591			.type = "ug3105",
 592			.addr = 0x70,
 593			.dev_name = "ug3105",
 594			.swnode = &asus_tf103c_ug3105_node,
 595		},
 596		.adapter_path = "\\_SB_.I2C1",
 597	}, {
 598		/* ak09911 compass */
 599		.board_info = {
 600			.type = "ak09911",
 601			.addr = 0x0c,
 602			.dev_name = "ak09911",
 603		},
 604		.adapter_path = "\\_SB_.I2C5",
 605	}, {
 606		/* kxtj21009 accel */
 607		.board_info = {
 608			.type = "kxtj21009",
 609			.addr = 0x0f,
 610			.dev_name = "kxtj21009",
 611			.swnode = &asus_tf103c_accel_node,
 612		},
 613		.adapter_path = "\\_SB_.I2C5",
 614	}, {
 615		/* atmel touchscreen */
 616		.board_info = {
 617			.type = "atmel_mxt_ts",
 618			.addr = 0x4a,
 619			.dev_name = "atmel_mxt_ts",
 620			.swnode = &asus_tf103c_touchscreen_node,
 621		},
 622		.adapter_path = "\\_SB_.I2C6",
 623		.irq_data = {
 624			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 625			.chip = "INT33FC:02",
 626			.index = 28,
 627			.trigger = ACPI_EDGE_SENSITIVE,
 628			.polarity = ACPI_ACTIVE_LOW,
 629		},
 630	},
 631};
 632
 633static struct gpiod_lookup_table * const asus_tf103c_gpios[] = {
 634	&int3496_gpo2_pin22_gpios,
 635	NULL
 636};
 637
 638static const struct x86_dev_info asus_tf103c_info __initconst = {
 639	.i2c_client_info = asus_tf103c_i2c_clients,
 640	.i2c_client_count = ARRAY_SIZE(asus_tf103c_i2c_clients),
 641	.pdev_info = asus_me176c_tf103c_pdevs,
 642	.pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs),
 643	.gpiod_lookup_tables = asus_tf103c_gpios,
 644	.bat_swnode = &asus_tf103c_battery_node,
 645	.modules = bq24190_modules,
 646	.invalid_aei_gpiochip = "INT33FC:02",
 647	.init = asus_me176c_tf103c_init,
 648};
 649
 650/*
 651 * When booted with the BIOS set to Android mode the Chuwi Hi8 (CWI509) DSDT
 652 * contains a whole bunch of bogus ACPI I2C devices and is missing entries
 653 * for the touchscreen and the accelerometer.
 654 */
 655static const struct property_entry chuwi_hi8_gsl1680_props[] = {
 656	PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
 657	PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
 658	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
 659	PROPERTY_ENTRY_BOOL("silead,home-button"),
 660	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi8.fw"),
 661	{ }
 662};
 663
 664static const struct software_node chuwi_hi8_gsl1680_node = {
 665	.properties = chuwi_hi8_gsl1680_props,
 666};
 667
 668static const char * const chuwi_hi8_mount_matrix[] = {
 669	"1", "0", "0",
 670	"0", "-1", "0",
 671	"0", "0", "1"
 672};
 673
 674static const struct property_entry chuwi_hi8_bma250e_props[] = {
 675	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", chuwi_hi8_mount_matrix),
 676	{ }
 677};
 678
 679static const struct software_node chuwi_hi8_bma250e_node = {
 680	.properties = chuwi_hi8_bma250e_props,
 681};
 682
 683static const struct x86_i2c_client_info chuwi_hi8_i2c_clients[] __initconst = {
 684	{
 685		/* Silead touchscreen */
 686		.board_info = {
 687			.type = "gsl1680",
 688			.addr = 0x40,
 689			.swnode = &chuwi_hi8_gsl1680_node,
 690		},
 691		.adapter_path = "\\_SB_.I2C4",
 692		.irq_data = {
 693			.type = X86_ACPI_IRQ_TYPE_APIC,
 694			.index = 0x44,
 695			.trigger = ACPI_EDGE_SENSITIVE,
 696			.polarity = ACPI_ACTIVE_HIGH,
 697		},
 698	}, {
 699		/* BMA250E accelerometer */
 700		.board_info = {
 701			.type = "bma250e",
 702			.addr = 0x18,
 703			.swnode = &chuwi_hi8_bma250e_node,
 704		},
 705		.adapter_path = "\\_SB_.I2C3",
 706		.irq_data = {
 707			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 708			.chip = "INT33FC:02",
 709			.index = 23,
 710			.trigger = ACPI_LEVEL_SENSITIVE,
 711			.polarity = ACPI_ACTIVE_HIGH,
 712		},
 713	},
 714};
 715
 716static int __init chuwi_hi8_init(void)
 717{
 718	/*
 719	 * Avoid the acpi_unregister_gsi() call in x86_acpi_irq_helper_get()
 720	 * breaking the touchscreen + logging various errors when the Windows
 721	 * BIOS is used.
 722	 */
 723	if (acpi_dev_present("MSSL0001", NULL, 1))
 724		return -ENODEV;
 725
 726	return 0;
 727}
 728
 729static const struct x86_dev_info chuwi_hi8_info __initconst = {
 730	.i2c_client_info = chuwi_hi8_i2c_clients,
 731	.i2c_client_count = ARRAY_SIZE(chuwi_hi8_i2c_clients),
 732	.init = chuwi_hi8_init,
 733};
 734
 735#define CZC_EC_EXTRA_PORT	0x68
 736#define CZC_EC_ANDROID_KEYS	0x63
 737
 738static int __init czc_p10t_init(void)
 739{
 740	/*
 741	 * The device boots up in "Windows 7" mode, when the home button sends a
 742	 * Windows specific key sequence (Left Meta + D) and the second button
 743	 * sends an unknown one while also toggling the Radio Kill Switch.
 744	 * This is a surprising behavior when the second button is labeled "Back".
 745	 *
 746	 * The vendor-supplied Android-x86 build switches the device to a "Android"
 747	 * mode by writing value 0x63 to the I/O port 0x68. This just seems to just
 748	 * set bit 6 on address 0x96 in the EC region; switching the bit directly
 749	 * seems to achieve the same result. It uses a "p10t_switcher" to do the
 750	 * job. It doesn't seem to be able to do anything else, and no other use
 751	 * of the port 0x68 is known.
 752	 *
 753	 * In the Android mode, the home button sends just a single scancode,
 754	 * which can be handled in Linux userspace more reasonably and the back
 755	 * button only sends a scancode without toggling the kill switch.
 756	 * The scancode can then be mapped either to Back or RF Kill functionality
 757	 * in userspace, depending on how the button is labeled on that particular
 758	 * model.
 759	 */
 760	outb(CZC_EC_ANDROID_KEYS, CZC_EC_EXTRA_PORT);
 761	return 0;
 762}
 763
 764static const struct x86_dev_info czc_p10t __initconst = {
 765	.init = czc_p10t_init,
 766};
 767
 768/* Lenovo Yoga Book X90F / X91F / X91L need manual instantiation of the fg client */
 769static const struct x86_i2c_client_info lenovo_yogabook_x9x_i2c_clients[] __initconst = {
 770	{
 771		/* BQ27542 fuel-gauge */
 772		.board_info = {
 773			.type = "bq27542",
 774			.addr = 0x55,
 775			.dev_name = "bq27542",
 776			.swnode = &fg_bq25890_supply_node,
 777		},
 778		.adapter_path = "\\_SB_.PCI0.I2C1",
 779	},
 780};
 781
 782static const struct x86_dev_info lenovo_yogabook_x9x_info __initconst = {
 783	.i2c_client_info = lenovo_yogabook_x9x_i2c_clients,
 784	.i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x9x_i2c_clients),
 785};
 786
 787/* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */
 788static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
 789	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
 790	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
 791	PROPERTY_ENTRY_BOOL("omit-battery-class"),
 792	PROPERTY_ENTRY_BOOL("disable-reset"),
 793	{ }
 794};
 795
 796static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
 797	.properties = lenovo_yoga_tab2_830_1050_bq24190_props,
 798};
 799
 800/* This gets filled by lenovo_yoga_tab2_830_1050_init() */
 801static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
 802
 803static struct lp855x_platform_data lenovo_yoga_tab2_830_1050_lp8557_pdata = {
 804	.device_control = 0x86,
 805	.initial_brightness = 128,
 806};
 807
 808static const struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initconst = {
 809	{
 810		/* bq24292i battery charger */
 811		.board_info = {
 812			.type = "bq24190",
 813			.addr = 0x6b,
 814			.dev_name = "bq24292i",
 815			.swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
 816			.platform_data = &bq24190_pdata,
 817		},
 818		.adapter_path = "\\_SB_.I2C1",
 819		.irq_data = {
 820			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 821			.chip = "INT33FC:02",
 822			.index = 2,
 823			.trigger = ACPI_EDGE_SENSITIVE,
 824			.polarity = ACPI_ACTIVE_HIGH,
 825		},
 826	}, {
 827		/* BQ27541 fuel-gauge */
 828		.board_info = {
 829			.type = "bq27541",
 830			.addr = 0x55,
 831			.dev_name = "bq27541",
 832			.swnode = &fg_bq24190_supply_node,
 833		},
 834		.adapter_path = "\\_SB_.I2C1",
 835	}, {
 836		/* Synaptics RMI touchscreen */
 837		.board_info = {
 838			.type = "rmi4_i2c",
 839			.addr = 0x38,
 840			.dev_name = "rmi4_i2c",
 841			.platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
 842		},
 843		.adapter_path = "\\_SB_.I2C6",
 844		.irq_data = {
 845			.type = X86_ACPI_IRQ_TYPE_APIC,
 846			.index = 0x45,
 847			.trigger = ACPI_EDGE_SENSITIVE,
 848			.polarity = ACPI_ACTIVE_HIGH,
 849		},
 850	}, {
 851		/* LP8557 Backlight controller */
 852		.board_info = {
 853			.type = "lp8557",
 854			.addr = 0x2c,
 855			.dev_name = "lp8557",
 856			.platform_data = &lenovo_yoga_tab2_830_1050_lp8557_pdata,
 857		},
 858		.adapter_path = "\\_SB_.I2C3",
 859	},
 860};
 861
 862static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
 863	.dev_id = "intel-int3496",
 864	.table = {
 865		GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
 866		GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
 867		{ }
 868	},
 869};
 870
 871#define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
 872
 873static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = {
 874	.dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME,
 875	.table = {
 876		GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH),
 877		GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH),
 878		GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
 879		GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW),
 880		{ }
 881	},
 882};
 883
 884static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = {
 885	&lenovo_yoga_tab2_830_1050_int3496_gpios,
 886	&lenovo_yoga_tab2_830_1050_codec_gpios,
 887	NULL
 888};
 889
 890static int __init lenovo_yoga_tab2_830_1050_init(void);
 891static void lenovo_yoga_tab2_830_1050_exit(void);
 892
 893static struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initdata = {
 894	.i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
 895	/* i2c_client_count gets set by lenovo_yoga_tab2_830_1050_init() */
 896	.pdev_info = int3496_pdevs,
 897	.pdev_count = ARRAY_SIZE(int3496_pdevs),
 898	.gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios,
 899	.bat_swnode = &generic_lipo_hv_4v35_battery_node,
 900	.modules = bq24190_modules,
 901	.invalid_aei_gpiochip = "INT33FC:02",
 902	.init = lenovo_yoga_tab2_830_1050_init,
 903	.exit = lenovo_yoga_tab2_830_1050_exit,
 904};
 905
 906/*
 907 * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
 908 * mainboard, but they need some different treatment related to the display:
 909 * 1. The 830 uses a portrait LCD panel with a landscape touchscreen, requiring
 910 *    the touchscreen driver to adjust the touch-coords to match the LCD.
 911 * 2. Both use an TI LP8557 LED backlight controller. On the 1050 the LP8557's
 912 *    PWM input is connected to the PMIC's PWM output and everything works fine
 913 *    with the defaults programmed into the LP8557 by the BIOS.
 914 *    But on the 830 the LP8557's PWM input is connected to a PWM output coming
 915 *    from the LCD panel's controller. The Android code has a hack in the i915
 916 *    driver to write the non-standard DSI reg 0x9f with the desired backlight
 917 *    level to set the duty-cycle of the LCD's PWM output.
 918 *
 919 *    To avoid having to have a similar hack in the mainline kernel the LP8557
 920 *    entry in lenovo_yoga_tab2_830_1050_i2c_clients instead just programs the
 921 *    LP8557 to directly set the level, ignoring the PWM input. This means that
 922 *    the LP8557 i2c_client should only be instantiated on the 830.
 923 */
 924static int __init lenovo_yoga_tab2_830_1050_init_display(void)
 925{
 926	struct gpio_desc *gpiod;
 927	int ret;
 928
 929	/* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
 930	ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, &gpiod);
 931	if (ret)
 932		return ret;
 933
 934	ret = gpiod_get_value_cansleep(gpiod);
 935	if (ret) {
 936		pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
 937		lenovo_yoga_tab2_830_1050_info.i2c_client_count =
 938			ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients) - 1;
 939	} else {
 940		pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
 941		lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
 942		lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
 943		lenovo_yoga_tab2_830_1050_info.i2c_client_count =
 944			ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients);
 945	}
 946
 947	return 0;
 948}
 949
 950/* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
 951static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
 952	PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
 953			  "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
 954
 955static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
 956static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
 957
 958static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
 959{
 960	struct device *codec_dev;
 961	struct pinctrl *pinctrl;
 962	int ret;
 963
 964	codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
 965					    LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
 966	if (!codec_dev) {
 967		pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
 968		return -ENODEV;
 969	}
 970
 971	ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
 972	if (ret)
 973		goto err_put_device;
 974
 975	pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
 976	if (IS_ERR(pinctrl)) {
 977		ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
 978		goto err_unregister_mappings;
 979	}
 980
 981	/* We're done with the codec_dev now */
 982	put_device(codec_dev);
 983
 984	lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
 985	return 0;
 986
 987err_unregister_mappings:
 988	pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
 989err_put_device:
 990	put_device(codec_dev);
 991	return ret;
 992}
 993
 994/*
 995 * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off
 996 * gets used as pm_power_off handler. This causes "poweroff" on these tablets
 997 * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice*
 998 * followed by a normal 3 second press to recover. Avoid this by doing an EFI
 999 * poweroff instead.
1000 */
1001static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
1002{
1003	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
1004
1005	return NOTIFY_DONE;
1006}
1007
1008static int __init lenovo_yoga_tab2_830_1050_init(void)
1009{
1010	int ret;
1011
1012	ret = lenovo_yoga_tab2_830_1050_init_display();
1013	if (ret)
1014		return ret;
1015
1016	ret = lenovo_yoga_tab2_830_1050_init_codec();
1017	if (ret)
1018		return ret;
1019
1020	/* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */
1021	lenovo_yoga_tab2_830_1050_sys_off_handler =
1022		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
1023					 lenovo_yoga_tab2_830_1050_power_off, NULL);
1024	if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
1025		return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
1026
1027	return 0;
1028}
1029
1030static void lenovo_yoga_tab2_830_1050_exit(void)
1031{
1032	unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
1033
1034	if (lenovo_yoga_tab2_830_1050_codec_pinctrl) {
1035		pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
1036		pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
1037	}
1038}
1039
1040/* Lenovo Yoga Tab 3 Pro YT3-X90F */
1041
1042/*
1043 * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers,
1044 * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c.
1045 */
1046static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" };
1047static const char * const bq25890_1_psy[] = { "bq25890-charger-1" };
1048
1049static const struct property_entry fg_bq25890_1_supply_props[] = {
1050	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy),
1051	{ }
1052};
1053
1054static const struct software_node fg_bq25890_1_supply_node = {
1055	.properties = fg_bq25890_1_supply_props,
1056};
1057
1058/* bq25892 charger settings for the flat lipo battery behind the screen */
1059static const struct property_entry lenovo_yt3_bq25892_0_props[] = {
1060	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers),
1061	PROPERTY_ENTRY_STRING("linux,power-supply-name", "bq25892-second-chrg"),
1062	PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40),
1063	PROPERTY_ENTRY_BOOL("linux,skip-reset"),
1064	/* Values taken from Android Factory Image */
1065	PROPERTY_ENTRY_U32("ti,charge-current", 2048000),
1066	PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
1067	PROPERTY_ENTRY_U32("ti,termination-current", 128000),
1068	PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
1069	PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000),
1070	PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
1071	PROPERTY_ENTRY_U32("ti,boost-max-current", 500000),
1072	PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
1073	{ }
1074};
1075
1076static const struct software_node lenovo_yt3_bq25892_0_node = {
1077	.properties = lenovo_yt3_bq25892_0_props,
1078};
1079
1080static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
1081	{
1082		/* bq27500 fuel-gauge for the flat lipo battery behind the screen */
1083		.board_info = {
1084			.type = "bq27500",
1085			.addr = 0x55,
1086			.dev_name = "bq27500_0",
1087			.swnode = &fg_bq25890_supply_node,
1088		},
1089		.adapter_path = "\\_SB_.PCI0.I2C1",
1090	}, {
1091		/* bq25892 charger for the flat lipo battery behind the screen */
1092		.board_info = {
1093			.type = "bq25892",
1094			.addr = 0x6b,
1095			.dev_name = "bq25892_0",
1096			.swnode = &lenovo_yt3_bq25892_0_node,
1097		},
1098		.adapter_path = "\\_SB_.PCI0.I2C1",
1099		.irq_data = {
1100			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
1101			.chip = "INT33FF:01",
1102			.index = 5,
1103			.trigger = ACPI_EDGE_SENSITIVE,
1104			.polarity = ACPI_ACTIVE_LOW,
1105		},
1106	}, {
1107		/* bq27500 fuel-gauge for the round li-ion cells in the hinge */
1108		.board_info = {
1109			.type = "bq27500",
1110			.addr = 0x55,
1111			.dev_name = "bq27500_1",
1112			.swnode = &fg_bq25890_1_supply_node,
1113		},
1114		.adapter_path = "\\_SB_.PCI0.I2C2",
1115	}
1116};
1117
1118static int __init lenovo_yt3_init(void)
1119{
1120	struct gpio_desc *gpiod;
1121	int ret;
1122
1123	/*
1124	 * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins
1125	 * connected to GPIOs, rather then having them hardwired to the correct
1126	 * values as is normally done.
1127	 *
1128	 * The bq25890_charger driver controls these through I2C, but this only
1129	 * works if not overridden by the pins. Set these pins here:
1130	 * 1. Set /CE to 0 to allow charging.
1131	 * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of
1132	 *    the main "bq25892_1" charger is used when necessary.
1133	 */
1134
1135	/* /CE pin */
1136	ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, &gpiod);
1137	if (ret < 0)
1138		return ret;
1139
1140	/*
1141	 * The gpio_desc returned by x86_android_tablet_get_gpiod() is a "raw"
1142	 * gpio_desc, that is there is no way to pass lookup-flags like
1143	 * GPIO_ACTIVE_LOW. Set the GPIO to 0 here to enable charging since
1144	 * the /CE pin is active-low, but not marked as such in the gpio_desc.
1145	 */
1146	gpiod_set_value(gpiod, 0);
1147
1148	/* OTG pin */
1149	ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, &gpiod);
1150	if (ret < 0)
1151		return ret;
1152
1153	gpiod_set_value(gpiod, 0);
1154
1155	return 0;
1156}
1157
1158static const struct x86_dev_info lenovo_yt3_info __initconst = {
1159	.i2c_client_info = lenovo_yt3_i2c_clients,
1160	.i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients),
1161	.init = lenovo_yt3_init,
1162};
1163
1164/* Medion Lifetab S10346 tablets have an Android factory img with everything hardcoded */
1165static const char * const medion_lifetab_s10346_accel_mount_matrix[] = {
1166	"0", "1", "0",
1167	"1", "0", "0",
1168	"0", "0", "1"
1169};
1170
1171static const struct property_entry medion_lifetab_s10346_accel_props[] = {
1172	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", medion_lifetab_s10346_accel_mount_matrix),
1173	{ }
1174};
1175
1176static const struct software_node medion_lifetab_s10346_accel_node = {
1177	.properties = medion_lifetab_s10346_accel_props,
1178};
1179
1180/* Note the LCD panel is mounted upside down, this is correctly indicated in the VBT */
1181static const struct property_entry medion_lifetab_s10346_touchscreen_props[] = {
1182	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
1183	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
1184	{ }
1185};
1186
1187static const struct software_node medion_lifetab_s10346_touchscreen_node = {
1188	.properties = medion_lifetab_s10346_touchscreen_props,
1189};
1190
1191static const struct x86_i2c_client_info medion_lifetab_s10346_i2c_clients[] __initconst = {
1192	{
1193		/* kxtj21009 accel */
1194		.board_info = {
1195			.type = "kxtj21009",
1196			.addr = 0x0f,
1197			.dev_name = "kxtj21009",
1198			.swnode = &medion_lifetab_s10346_accel_node,
1199		},
1200		.adapter_path = "\\_SB_.I2C3",
1201		.irq_data = {
1202			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
1203			.chip = "INT33FC:02",
1204			.index = 23,
1205			.trigger = ACPI_EDGE_SENSITIVE,
1206			.polarity = ACPI_ACTIVE_HIGH,
1207		},
1208	}, {
1209		/* goodix touchscreen */
1210		.board_info = {
1211			.type = "GDIX1001:00",
1212			.addr = 0x14,
1213			.dev_name = "goodix_ts",
1214			.swnode = &medion_lifetab_s10346_touchscreen_node,
1215		},
1216		.adapter_path = "\\_SB_.I2C4",
1217		.irq_data = {
1218			.type = X86_ACPI_IRQ_TYPE_APIC,
1219			.index = 0x44,
1220			.trigger = ACPI_EDGE_SENSITIVE,
1221			.polarity = ACPI_ACTIVE_LOW,
1222		},
1223	},
1224};
1225
1226static struct gpiod_lookup_table medion_lifetab_s10346_goodix_gpios = {
1227	.dev_id = "i2c-goodix_ts",
1228	.table = {
1229		GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH),
1230		GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH),
1231		{ }
1232	},
1233};
1234
1235static struct gpiod_lookup_table * const medion_lifetab_s10346_gpios[] = {
1236	&medion_lifetab_s10346_goodix_gpios,
1237	NULL
1238};
1239
1240static const struct x86_dev_info medion_lifetab_s10346_info __initconst = {
1241	.i2c_client_info = medion_lifetab_s10346_i2c_clients,
1242	.i2c_client_count = ARRAY_SIZE(medion_lifetab_s10346_i2c_clients),
1243	.gpiod_lookup_tables = medion_lifetab_s10346_gpios,
1244};
1245
1246/* Nextbook Ares 8 tablets have an Android factory img with everything hardcoded */
1247static const char * const nextbook_ares8_accel_mount_matrix[] = {
1248	"0", "-1", "0",
1249	"-1", "0", "0",
1250	"0", "0", "1"
1251};
1252
1253static const struct property_entry nextbook_ares8_accel_props[] = {
1254	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", nextbook_ares8_accel_mount_matrix),
1255	{ }
1256};
1257
1258static const struct software_node nextbook_ares8_accel_node = {
1259	.properties = nextbook_ares8_accel_props,
1260};
1261
1262static const struct property_entry nextbook_ares8_touchscreen_props[] = {
1263	PROPERTY_ENTRY_U32("touchscreen-size-x", 800),
1264	PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
1265	{ }
1266};
1267
1268static const struct software_node nextbook_ares8_touchscreen_node = {
1269	.properties = nextbook_ares8_touchscreen_props,
1270};
1271
1272static const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst = {
1273	{
1274		/* Freescale MMA8653FC accel */
1275		.board_info = {
1276			.type = "mma8653",
1277			.addr = 0x1d,
1278			.dev_name = "mma8653",
1279			.swnode = &nextbook_ares8_accel_node,
1280		},
1281		.adapter_path = "\\_SB_.I2C3",
1282	}, {
1283		/* FT5416DQ9 touchscreen controller */
1284		.board_info = {
1285			.type = "edt-ft5x06",
1286			.addr = 0x38,
1287			.dev_name = "ft5416",
1288			.swnode = &nextbook_ares8_touchscreen_node,
1289		},
1290		.adapter_path = "\\_SB_.I2C4",
1291		.irq_data = {
1292			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
1293			.chip = "INT33FC:02",
1294			.index = 3,
1295			.trigger = ACPI_EDGE_SENSITIVE,
1296			.polarity = ACPI_ACTIVE_LOW,
1297		},
1298	},
1299};
1300
1301static struct gpiod_lookup_table nextbook_ares8_int3496_gpios = {
1302	.dev_id = "intel-int3496",
1303	.table = {
1304		GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_HIGH),
1305		GPIO_LOOKUP("INT33FC:02", 18, "id", GPIO_ACTIVE_HIGH),
1306		{ }
1307	},
1308};
1309
1310static struct gpiod_lookup_table * const nextbook_ares8_gpios[] = {
1311	&nextbook_ares8_int3496_gpios,
1312	NULL
1313};
1314
1315static const struct x86_dev_info nextbook_ares8_info __initconst = {
1316	.i2c_client_info = nextbook_ares8_i2c_clients,
1317	.i2c_client_count = ARRAY_SIZE(nextbook_ares8_i2c_clients),
1318	.pdev_info = int3496_pdevs,
1319	.pdev_count = ARRAY_SIZE(int3496_pdevs),
1320	.gpiod_lookup_tables = nextbook_ares8_gpios,
1321	.invalid_aei_gpiochip = "INT33FC:02",
1322};
1323
1324/*
1325 * Whitelabel (sold as various brands) TM800A550L tablets.
1326 * These tablet's DSDT contains a whole bunch of bogus ACPI I2C devices
1327 * (removed through acpi_quirk_skip_i2c_client_enumeration()) and
1328 * the touchscreen fwnode has the wrong GPIOs.
1329 */
1330static const char * const whitelabel_tm800a550l_accel_mount_matrix[] = {
1331	"-1", "0", "0",
1332	"0", "1", "0",
1333	"0", "0", "1"
1334};
1335
1336static const struct property_entry whitelabel_tm800a550l_accel_props[] = {
1337	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", whitelabel_tm800a550l_accel_mount_matrix),
1338	{ }
1339};
1340
1341static const struct software_node whitelabel_tm800a550l_accel_node = {
1342	.properties = whitelabel_tm800a550l_accel_props,
1343};
1344
1345static const struct property_entry whitelabel_tm800a550l_goodix_props[] = {
1346	PROPERTY_ENTRY_STRING("firmware-name", "gt912-tm800a550l.fw"),
1347	PROPERTY_ENTRY_STRING("goodix,config-name", "gt912-tm800a550l.cfg"),
1348	PROPERTY_ENTRY_U32("goodix,main-clk", 54),
1349	{ }
1350};
1351
1352static const struct software_node whitelabel_tm800a550l_goodix_node = {
1353	.properties = whitelabel_tm800a550l_goodix_props,
1354};
1355
1356static const struct x86_i2c_client_info whitelabel_tm800a550l_i2c_clients[] __initconst = {
1357	{
1358		/* goodix touchscreen */
1359		.board_info = {
1360			.type = "GDIX1001:00",
1361			.addr = 0x14,
1362			.dev_name = "goodix_ts",
1363			.swnode = &whitelabel_tm800a550l_goodix_node,
1364		},
1365		.adapter_path = "\\_SB_.I2C2",
1366		.irq_data = {
1367			.type = X86_ACPI_IRQ_TYPE_APIC,
1368			.index = 0x44,
1369			.trigger = ACPI_EDGE_SENSITIVE,
1370			.polarity = ACPI_ACTIVE_HIGH,
1371		},
1372	}, {
1373		/* kxcj91008 accel */
1374		.board_info = {
1375			.type = "kxcj91008",
1376			.addr = 0x0f,
1377			.dev_name = "kxcj91008",
1378			.swnode = &whitelabel_tm800a550l_accel_node,
1379		},
1380		.adapter_path = "\\_SB_.I2C3",
1381	},
1382};
1383
1384static struct gpiod_lookup_table whitelabel_tm800a550l_goodix_gpios = {
1385	.dev_id = "i2c-goodix_ts",
1386	.table = {
1387		GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH),
1388		GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH),
1389		{ }
1390	},
1391};
1392
1393static struct gpiod_lookup_table * const whitelabel_tm800a550l_gpios[] = {
1394	&whitelabel_tm800a550l_goodix_gpios,
1395	NULL
1396};
1397
1398static const struct x86_dev_info whitelabel_tm800a550l_info __initconst = {
1399	.i2c_client_info = whitelabel_tm800a550l_i2c_clients,
1400	.i2c_client_count = ARRAY_SIZE(whitelabel_tm800a550l_i2c_clients),
1401	.gpiod_lookup_tables = whitelabel_tm800a550l_gpios,
1402};
1403
1404/*
1405 * If the EFI bootloader is not Xiaomi's own signed Android loader, then the
1406 * Xiaomi Mi Pad 2 X86 tablet sets OSID in the DSDT to 1 (Windows), causing
1407 * a bunch of devices to be hidden.
1408 *
1409 * This takes care of instantiating the hidden devices manually.
1410 */
1411static const struct x86_i2c_client_info xiaomi_mipad2_i2c_clients[] __initconst = {
1412	{
1413		/* BQ27520 fuel-gauge */
1414		.board_info = {
1415			.type = "bq27520",
1416			.addr = 0x55,
1417			.dev_name = "bq27520",
1418			.swnode = &fg_bq25890_supply_node,
1419		},
1420		.adapter_path = "\\_SB_.PCI0.I2C1",
1421	}, {
1422		/* KTD2026 RGB notification LED controller */
1423		.board_info = {
1424			.type = "ktd2026",
1425			.addr = 0x30,
1426			.dev_name = "ktd2026",
1427		},
1428		.adapter_path = "\\_SB_.PCI0.I2C3",
1429	},
1430};
1431
1432static const struct x86_dev_info xiaomi_mipad2_info __initconst = {
1433	.i2c_client_info = xiaomi_mipad2_i2c_clients,
1434	.i2c_client_count = ARRAY_SIZE(xiaomi_mipad2_i2c_clients),
1435};
1436
1437static const struct dmi_system_id x86_android_tablet_ids[] __initconst = {
1438	{
1439		/* Advantech MICA-071 */
1440		.matches = {
1441			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"),
1442			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"),
1443		},
1444		.driver_data = (void *)&advantech_mica_071_info,
1445	},
1446	{
1447		/* Asus MeMO Pad 7 ME176C */
1448		.matches = {
1449			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
1450			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"),
1451		},
1452		.driver_data = (void *)&asus_me176c_info,
1453	},
1454	{
1455		/* Asus TF103C */
1456		.matches = {
1457			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
1458			DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
1459		},
1460		.driver_data = (void *)&asus_tf103c_info,
1461	},
1462	{
1463		/* Chuwi Hi8 (CWI509) */
1464		.matches = {
1465			DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
1466			DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"),
1467			DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
1468			DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
1469		},
1470		.driver_data = (void *)&chuwi_hi8_info,
1471	},
1472	{
1473		/* CZC P10T */
1474		.ident = "CZC ODEON TPC-10 (\"P10T\")",
1475		.matches = {
1476			DMI_MATCH(DMI_SYS_VENDOR, "CZC"),
1477			DMI_MATCH(DMI_PRODUCT_NAME, "ODEON*TPC-10"),
1478		},
1479		.driver_data = (void *)&czc_p10t,
1480	},
1481	{
1482		/* CZC P10T variant */
1483		.ident = "ViewSonic ViewPad 10",
1484		.matches = {
1485			DMI_MATCH(DMI_SYS_VENDOR, "ViewSonic"),
1486			DMI_MATCH(DMI_PRODUCT_NAME, "VPAD10"),
1487		},
1488		.driver_data = (void *)&czc_p10t,
1489	},
1490	{
1491		/* Lenovo Yoga Book X90F / X91F / X91L */
1492		.matches = {
1493			/* Non exact match to match all versions */
1494			DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
1495		},
1496		.driver_data = (void *)&lenovo_yogabook_x9x_info,
1497	},
1498	{
1499		/*
1500		 * Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10"
1501		 * Lenovo Yoga Tablet 2 use the same mainboard)
1502		 */
1503		.matches = {
1504			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
1505			DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
1506			DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
1507			/* Partial match on beginning of BIOS version */
1508			DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
1509		},
1510		.driver_data = (void *)&lenovo_yoga_tab2_830_1050_info,
1511	},
1512	{
1513		/* Lenovo Yoga Tab 3 Pro YT3-X90F */
1514		.matches = {
1515			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
1516			DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
1517			DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
1518		},
1519		.driver_data = (void *)&lenovo_yt3_info,
1520	},
1521	{
1522		/* Medion Lifetab S10346 */
1523		.matches = {
1524			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1525			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1526			/* Above strings are much too generic, also match on BIOS date */
1527			DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"),
1528		},
1529		.driver_data = (void *)&medion_lifetab_s10346_info,
1530	},
1531	{
1532		/* Nextbook Ares 8 */
1533		.matches = {
1534			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
1535			DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"),
1536		},
1537		.driver_data = (void *)&nextbook_ares8_info,
1538	},
1539	{
1540		/* Whitelabel (sold as various brands) TM800A550L */
1541		.matches = {
1542			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1543			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1544			/* Above strings are too generic, also match on BIOS version */
1545			DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"),
1546		},
1547		.driver_data = (void *)&whitelabel_tm800a550l_info,
1548	},
1549	{
1550		/* Xiaomi Mi Pad 2 */
1551		.matches = {
1552			DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
1553			DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
1554		},
1555		.driver_data = (void *)&xiaomi_mipad2_info,
1556	},
1557	{ }
1558};
1559MODULE_DEVICE_TABLE(dmi, x86_android_tablet_ids);
1560
1561static int i2c_client_count;
1562static int pdev_count;
1563static int serdev_count;
1564static struct i2c_client **i2c_clients;
1565static struct platform_device **pdevs;
1566static struct serdev_device **serdevs;
1567static struct gpiod_lookup_table * const *gpiod_lookup_tables;
1568static const struct software_node *bat_swnode;
1569static void (*exit_handler)(void);
1570
1571static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info,
1572					     int idx)
1573{
1574	const struct x86_i2c_client_info *client_info = &dev_info->i2c_client_info[idx];
1575	struct i2c_board_info board_info = client_info->board_info;
1576	struct i2c_adapter *adap;
1577	acpi_handle handle;
1578	acpi_status status;
1579
1580	board_info.irq = x86_acpi_irq_helper_get(&client_info->irq_data);
1581	if (board_info.irq < 0)
1582		return board_info.irq;
1583
1584	status = acpi_get_handle(NULL, client_info->adapter_path, &handle);
1585	if (ACPI_FAILURE(status)) {
1586		pr_err("Error could not get %s handle\n", client_info->adapter_path);
1587		return -ENODEV;
1588	}
1589
1590	adap = i2c_acpi_find_adapter_by_handle(handle);
1591	if (!adap) {
1592		pr_err("error could not get %s adapter\n", client_info->adapter_path);
1593		return -ENODEV;
1594	}
1595
1596	i2c_clients[idx] = i2c_new_client_device(adap, &board_info);
1597	put_device(&adap->dev);
1598	if (IS_ERR(i2c_clients[idx]))
1599		return dev_err_probe(&adap->dev, PTR_ERR(i2c_clients[idx]),
1600				      "creating I2C-client %d\n", idx);
1601
1602	return 0;
1603}
1604
1605static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx)
1606{
1607	struct acpi_device *ctrl_adev, *serdev_adev;
1608	struct serdev_device *serdev;
1609	struct device *ctrl_dev;
1610	int ret = -ENODEV;
1611
1612	ctrl_adev = acpi_dev_get_first_match_dev(info->ctrl_hid, info->ctrl_uid, -1);
1613	if (!ctrl_adev) {
1614		pr_err("error could not get %s/%s ctrl adev\n",
1615		       info->ctrl_hid, info->ctrl_uid);
1616		return -ENODEV;
1617	}
1618
1619	serdev_adev = acpi_dev_get_first_match_dev(info->serdev_hid, NULL, -1);
1620	if (!serdev_adev) {
1621		pr_err("error could not get %s serdev adev\n", info->serdev_hid);
1622		goto put_ctrl_adev;
1623	}
1624
1625	/* get_first_physical_node() returns a weak ref, no need to put() it */
1626	ctrl_dev = acpi_get_first_physical_node(ctrl_adev);
1627	if (!ctrl_dev)	{
1628		pr_err("error could not get %s/%s ctrl physical dev\n",
1629		       info->ctrl_hid, info->ctrl_uid);
1630		goto put_serdev_adev;
1631	}
1632
1633	/* ctrl_dev now points to the controller's parent, get the controller */
1634	ctrl_dev = device_find_child_by_name(ctrl_dev, info->ctrl_devname);
1635	if (!ctrl_dev) {
1636		pr_err("error could not get %s/%s %s ctrl dev\n",
1637		       info->ctrl_hid, info->ctrl_uid, info->ctrl_devname);
1638		goto put_serdev_adev;
1639	}
1640
1641	serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev));
1642	if (!serdev) {
1643		ret = -ENOMEM;
1644		goto put_serdev_adev;
1645	}
1646
1647	ACPI_COMPANION_SET(&serdev->dev, serdev_adev);
1648	acpi_device_set_enumerated(serdev_adev);
1649
1650	ret = serdev_device_add(serdev);
1651	if (ret) {
1652		dev_err(&serdev->dev, "error %d adding serdev\n", ret);
1653		serdev_device_put(serdev);
1654		goto put_serdev_adev;
1655	}
1656
1657	serdevs[idx] = serdev;
1658
1659put_serdev_adev:
1660	acpi_dev_put(serdev_adev);
1661put_ctrl_adev:
1662	acpi_dev_put(ctrl_adev);
1663	return ret;
1664}
1665
1666static void x86_android_tablet_cleanup(void)
1667{
1668	int i;
1669
1670	for (i = 0; i < serdev_count; i++) {
1671		if (serdevs[i])
1672			serdev_device_remove(serdevs[i]);
1673	}
1674
1675	kfree(serdevs);
1676
1677	for (i = 0; i < pdev_count; i++)
1678		platform_device_unregister(pdevs[i]);
1679
1680	kfree(pdevs);
1681
1682	for (i = 0; i < i2c_client_count; i++)
1683		i2c_unregister_device(i2c_clients[i]);
1684
1685	kfree(i2c_clients);
1686
1687	if (exit_handler)
1688		exit_handler();
1689
1690	for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++)
1691		gpiod_remove_lookup_table(gpiod_lookup_tables[i]);
1692
1693	software_node_unregister(bat_swnode);
1694}
1695
1696static __init int x86_android_tablet_init(void)
1697{
1698	const struct x86_dev_info *dev_info;
1699	const struct dmi_system_id *id;
1700	struct gpio_chip *chip;
1701	int i, ret = 0;
1702
1703	id = dmi_first_match(x86_android_tablet_ids);
1704	if (!id)
1705		return -ENODEV;
1706
1707	dev_info = id->driver_data;
1708
1709	/*
1710	 * The broken DSDTs on these devices often also include broken
1711	 * _AEI (ACPI Event Interrupt) handlers, disable these.
1712	 */
1713	if (dev_info->invalid_aei_gpiochip) {
1714		chip = gpiochip_find(dev_info->invalid_aei_gpiochip,
1715				     gpiochip_find_match_label);
1716		if (!chip) {
1717			pr_err("error cannot find GPIO chip %s\n", dev_info->invalid_aei_gpiochip);
1718			return -ENODEV;
1719		}
1720		acpi_gpiochip_free_interrupts(chip);
1721	}
1722
1723	/*
1724	 * Since this runs from module_init() it cannot use -EPROBE_DEFER,
1725	 * instead pre-load any modules which are listed as requirements.
1726	 */
1727	for (i = 0; dev_info->modules && dev_info->modules[i]; i++)
1728		request_module(dev_info->modules[i]);
1729
1730	bat_swnode = dev_info->bat_swnode;
1731	if (bat_swnode) {
1732		ret = software_node_register(bat_swnode);
1733		if (ret)
1734			return ret;
1735	}
1736
1737	gpiod_lookup_tables = dev_info->gpiod_lookup_tables;
1738	for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++)
1739		gpiod_add_lookup_table(gpiod_lookup_tables[i]);
1740
1741	if (dev_info->init) {
1742		ret = dev_info->init();
1743		if (ret < 0) {
1744			x86_android_tablet_cleanup();
1745			return ret;
1746		}
1747		exit_handler = dev_info->exit;
1748	}
1749
1750	i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL);
1751	if (!i2c_clients) {
1752		x86_android_tablet_cleanup();
1753		return -ENOMEM;
1754	}
1755
1756	i2c_client_count = dev_info->i2c_client_count;
1757	for (i = 0; i < i2c_client_count; i++) {
1758		ret = x86_instantiate_i2c_client(dev_info, i);
1759		if (ret < 0) {
1760			x86_android_tablet_cleanup();
1761			return ret;
1762		}
1763	}
1764
1765	pdevs = kcalloc(dev_info->pdev_count, sizeof(*pdevs), GFP_KERNEL);
1766	if (!pdevs) {
1767		x86_android_tablet_cleanup();
1768		return -ENOMEM;
1769	}
1770
1771	pdev_count = dev_info->pdev_count;
1772	for (i = 0; i < pdev_count; i++) {
1773		pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]);
1774		if (IS_ERR(pdevs[i])) {
1775			x86_android_tablet_cleanup();
1776			return PTR_ERR(pdevs[i]);
1777		}
1778	}
1779
1780	serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL);
1781	if (!serdevs) {
1782		x86_android_tablet_cleanup();
1783		return -ENOMEM;
1784	}
1785
1786	serdev_count = dev_info->serdev_count;
1787	for (i = 0; i < serdev_count; i++) {
1788		ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i);
1789		if (ret < 0) {
1790			x86_android_tablet_cleanup();
1791			return ret;
1792		}
1793	}
1794
1795	return 0;
1796}
1797
1798module_init(x86_android_tablet_init);
1799module_exit(x86_android_tablet_cleanup);
1800
1801MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
1802MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver");
1803MODULE_LICENSE("GPL");