162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Board info for Lenovo X86 tablets which ship with Android as the factory image
462306a36Sopenharmony_ci * and which have broken DSDT tables. The factory kernels shipped on these
562306a36Sopenharmony_ci * devices typically have a bunch of things hardcoded, rather than specified
662306a36Sopenharmony_ci * in their DSDT.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/efi.h>
1462306a36Sopenharmony_ci#include <linux/gpio/machine.h>
1562306a36Sopenharmony_ci#include <linux/mfd/intel_soc_pmic.h>
1662306a36Sopenharmony_ci#include <linux/pinctrl/consumer.h>
1762306a36Sopenharmony_ci#include <linux/pinctrl/machine.h>
1862306a36Sopenharmony_ci#include <linux/platform_data/lp855x.h>
1962306a36Sopenharmony_ci#include <linux/platform_device.h>
2062306a36Sopenharmony_ci#include <linux/reboot.h>
2162306a36Sopenharmony_ci#include <linux/rmi.h>
2262306a36Sopenharmony_ci#include <linux/spi/spi.h>
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#include "shared-psy-info.h"
2562306a36Sopenharmony_ci#include "x86-android-tablets.h"
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/*
2862306a36Sopenharmony_ci * Various Lenovo models use a TI LP8557 LED backlight controller with its PWM
2962306a36Sopenharmony_ci * input connected to a PWM output coming from the LCD panel's controller.
3062306a36Sopenharmony_ci * The Android kernels have a hack in the i915 driver to write a non-standard
3162306a36Sopenharmony_ci * panel specific DSI register to set the duty-cycle of the LCD's PWM output.
3262306a36Sopenharmony_ci *
3362306a36Sopenharmony_ci * To avoid having to have a similar hack in the mainline kernel program the
3462306a36Sopenharmony_ci * LP8557 to directly set the level and use the lp855x_bl driver for control.
3562306a36Sopenharmony_ci */
3662306a36Sopenharmony_cistatic struct lp855x_platform_data lenovo_lp8557_pdata = {
3762306a36Sopenharmony_ci	.device_control = 0x86,
3862306a36Sopenharmony_ci	.initial_brightness = 128,
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/* Lenovo Yoga Book X90F / X90L's Android factory img has everything hardcoded */
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistatic const struct property_entry lenovo_yb1_x90_wacom_props[] = {
4462306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("hid-descr-addr", 0x0001),
4562306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 150),
4662306a36Sopenharmony_ci	{ }
4762306a36Sopenharmony_ci};
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistatic const struct software_node lenovo_yb1_x90_wacom_node = {
5062306a36Sopenharmony_ci	.properties = lenovo_yb1_x90_wacom_props,
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/*
5462306a36Sopenharmony_ci * The HiDeep IST940E touchscreen comes up in I2C-HID mode. The native protocol
5562306a36Sopenharmony_ci * reports ABS_MT_PRESSURE and ABS_MT_TOUCH_MAJOR which are not reported in HID
5662306a36Sopenharmony_ci * mode, so using native mode is preferred.
5762306a36Sopenharmony_ci * It could alternatively be used in HID mode by changing the properties to:
5862306a36Sopenharmony_ci *	PROPERTY_ENTRY_U32("hid-descr-addr", 0x0020),
5962306a36Sopenharmony_ci *	PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
6062306a36Sopenharmony_ci * and changing board_info.type to "hid-over-i2c".
6162306a36Sopenharmony_ci */
6262306a36Sopenharmony_cistatic const struct property_entry lenovo_yb1_x90_hideep_ts_props[] = {
6362306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("touchscreen-size-x", 1200),
6462306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
6562306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("touchscreen-max-pressure", 16384),
6662306a36Sopenharmony_ci	PROPERTY_ENTRY_BOOL("hideep,force-native-protocol"),
6762306a36Sopenharmony_ci	{ }
6862306a36Sopenharmony_ci};
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistatic const struct software_node lenovo_yb1_x90_hideep_ts_node = {
7162306a36Sopenharmony_ci	.properties = lenovo_yb1_x90_hideep_ts_props,
7262306a36Sopenharmony_ci};
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistatic const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst = {
7562306a36Sopenharmony_ci	{
7662306a36Sopenharmony_ci		/* BQ27542 fuel-gauge */
7762306a36Sopenharmony_ci		.board_info = {
7862306a36Sopenharmony_ci			.type = "bq27542",
7962306a36Sopenharmony_ci			.addr = 0x55,
8062306a36Sopenharmony_ci			.dev_name = "bq27542",
8162306a36Sopenharmony_ci			.swnode = &fg_bq25890_supply_node,
8262306a36Sopenharmony_ci		},
8362306a36Sopenharmony_ci		.adapter_path = "\\_SB_.PCI0.I2C1",
8462306a36Sopenharmony_ci	}, {
8562306a36Sopenharmony_ci		/* Goodix Touchscreen in keyboard half */
8662306a36Sopenharmony_ci		.board_info = {
8762306a36Sopenharmony_ci			.type = "GDIX1001:00",
8862306a36Sopenharmony_ci			.addr = 0x14,
8962306a36Sopenharmony_ci			.dev_name = "goodix_ts",
9062306a36Sopenharmony_ci		},
9162306a36Sopenharmony_ci		.adapter_path = "\\_SB_.PCI0.I2C2",
9262306a36Sopenharmony_ci		.irq_data = {
9362306a36Sopenharmony_ci			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
9462306a36Sopenharmony_ci			.chip = "INT33FF:01",
9562306a36Sopenharmony_ci			.index = 56,
9662306a36Sopenharmony_ci			.trigger = ACPI_EDGE_SENSITIVE,
9762306a36Sopenharmony_ci			.polarity = ACPI_ACTIVE_LOW,
9862306a36Sopenharmony_ci		},
9962306a36Sopenharmony_ci	}, {
10062306a36Sopenharmony_ci		/* Wacom Digitizer in keyboard half */
10162306a36Sopenharmony_ci		.board_info = {
10262306a36Sopenharmony_ci			.type = "hid-over-i2c",
10362306a36Sopenharmony_ci			.addr = 0x09,
10462306a36Sopenharmony_ci			.dev_name = "wacom",
10562306a36Sopenharmony_ci			.swnode = &lenovo_yb1_x90_wacom_node,
10662306a36Sopenharmony_ci		},
10762306a36Sopenharmony_ci		.adapter_path = "\\_SB_.PCI0.I2C4",
10862306a36Sopenharmony_ci		.irq_data = {
10962306a36Sopenharmony_ci			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
11062306a36Sopenharmony_ci			.chip = "INT33FF:01",
11162306a36Sopenharmony_ci			.index = 49,
11262306a36Sopenharmony_ci			.trigger = ACPI_LEVEL_SENSITIVE,
11362306a36Sopenharmony_ci			.polarity = ACPI_ACTIVE_LOW,
11462306a36Sopenharmony_ci		},
11562306a36Sopenharmony_ci	}, {
11662306a36Sopenharmony_ci		/* LP8557 Backlight controller */
11762306a36Sopenharmony_ci		.board_info = {
11862306a36Sopenharmony_ci			.type = "lp8557",
11962306a36Sopenharmony_ci			.addr = 0x2c,
12062306a36Sopenharmony_ci			.dev_name = "lp8557",
12162306a36Sopenharmony_ci			.platform_data = &lenovo_lp8557_pdata,
12262306a36Sopenharmony_ci		},
12362306a36Sopenharmony_ci		.adapter_path = "\\_SB_.PCI0.I2C4",
12462306a36Sopenharmony_ci	}, {
12562306a36Sopenharmony_ci		/* HiDeep IST940E Touchscreen in display half */
12662306a36Sopenharmony_ci		.board_info = {
12762306a36Sopenharmony_ci			.type = "hideep_ts",
12862306a36Sopenharmony_ci			.addr = 0x6c,
12962306a36Sopenharmony_ci			.dev_name = "hideep_ts",
13062306a36Sopenharmony_ci			.swnode = &lenovo_yb1_x90_hideep_ts_node,
13162306a36Sopenharmony_ci		},
13262306a36Sopenharmony_ci		.adapter_path = "\\_SB_.PCI0.I2C6",
13362306a36Sopenharmony_ci		.irq_data = {
13462306a36Sopenharmony_ci			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
13562306a36Sopenharmony_ci			.chip = "INT33FF:03",
13662306a36Sopenharmony_ci			.index = 77,
13762306a36Sopenharmony_ci			.trigger = ACPI_LEVEL_SENSITIVE,
13862306a36Sopenharmony_ci			.polarity = ACPI_ACTIVE_LOW,
13962306a36Sopenharmony_ci		},
14062306a36Sopenharmony_ci	},
14162306a36Sopenharmony_ci};
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_cistatic const struct platform_device_info lenovo_yb1_x90_pdevs[] __initconst = {
14462306a36Sopenharmony_ci	{
14562306a36Sopenharmony_ci		.name = "yogabook-touch-kbd-digitizer-switch",
14662306a36Sopenharmony_ci		.id = PLATFORM_DEVID_NONE,
14762306a36Sopenharmony_ci	},
14862306a36Sopenharmony_ci};
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci/*
15162306a36Sopenharmony_ci * DSDT says UART path is "\\_SB.PCIO.URT1" with a letter 'O' instead of
15262306a36Sopenharmony_ci * the number '0' add the link manually.
15362306a36Sopenharmony_ci */
15462306a36Sopenharmony_cistatic const struct x86_serdev_info lenovo_yb1_x90_serdevs[] __initconst = {
15562306a36Sopenharmony_ci	{
15662306a36Sopenharmony_ci		.ctrl_hid = "8086228A",
15762306a36Sopenharmony_ci		.ctrl_uid = "1",
15862306a36Sopenharmony_ci		.ctrl_devname = "serial0",
15962306a36Sopenharmony_ci		.serdev_hid = "BCM2E1A",
16062306a36Sopenharmony_ci	},
16162306a36Sopenharmony_ci};
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistatic const struct x86_gpio_button lenovo_yb1_x90_lid __initconst = {
16462306a36Sopenharmony_ci	.button = {
16562306a36Sopenharmony_ci		.code = SW_LID,
16662306a36Sopenharmony_ci		.active_low = true,
16762306a36Sopenharmony_ci		.desc = "lid_sw",
16862306a36Sopenharmony_ci		.type = EV_SW,
16962306a36Sopenharmony_ci		.wakeup = true,
17062306a36Sopenharmony_ci		.debounce_interval = 50,
17162306a36Sopenharmony_ci	},
17262306a36Sopenharmony_ci	.chip = "INT33FF:02",
17362306a36Sopenharmony_ci	.pin = 19,
17462306a36Sopenharmony_ci};
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_cistatic struct gpiod_lookup_table lenovo_yb1_x90_goodix_gpios = {
17762306a36Sopenharmony_ci	.dev_id = "i2c-goodix_ts",
17862306a36Sopenharmony_ci	.table = {
17962306a36Sopenharmony_ci		GPIO_LOOKUP("INT33FF:01", 53, "reset", GPIO_ACTIVE_HIGH),
18062306a36Sopenharmony_ci		GPIO_LOOKUP("INT33FF:01", 56, "irq", GPIO_ACTIVE_HIGH),
18162306a36Sopenharmony_ci		{ }
18262306a36Sopenharmony_ci	},
18362306a36Sopenharmony_ci};
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_cistatic struct gpiod_lookup_table lenovo_yb1_x90_hideep_gpios = {
18662306a36Sopenharmony_ci	.dev_id = "i2c-hideep_ts",
18762306a36Sopenharmony_ci	.table = {
18862306a36Sopenharmony_ci		GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
18962306a36Sopenharmony_ci		{ }
19062306a36Sopenharmony_ci	},
19162306a36Sopenharmony_ci};
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_cistatic struct gpiod_lookup_table lenovo_yb1_x90_wacom_gpios = {
19462306a36Sopenharmony_ci	.dev_id = "i2c-wacom",
19562306a36Sopenharmony_ci	.table = {
19662306a36Sopenharmony_ci		GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_LOW),
19762306a36Sopenharmony_ci		{ }
19862306a36Sopenharmony_ci	},
19962306a36Sopenharmony_ci};
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_cistatic struct gpiod_lookup_table * const lenovo_yb1_x90_gpios[] = {
20262306a36Sopenharmony_ci	&lenovo_yb1_x90_hideep_gpios,
20362306a36Sopenharmony_ci	&lenovo_yb1_x90_goodix_gpios,
20462306a36Sopenharmony_ci	&lenovo_yb1_x90_wacom_gpios,
20562306a36Sopenharmony_ci	NULL
20662306a36Sopenharmony_ci};
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_cistatic int __init lenovo_yb1_x90_init(void)
20962306a36Sopenharmony_ci{
21062306a36Sopenharmony_ci	/* Enable the regulators used by the touchscreens */
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	/* Vprog3B 3.0V used by the goodix touchscreen in the keyboard half */
21362306a36Sopenharmony_ci	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	/* Vprog4D 3.0V used by the HiDeep touchscreen in the display half */
21662306a36Sopenharmony_ci	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9f, 0x02, 0xff);
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	/* Vprog5A 1.8V used by the HiDeep touchscreen in the display half */
21962306a36Sopenharmony_ci	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	/* Vprog5B 1.8V used by the goodix touchscreen in the keyboard half */
22262306a36Sopenharmony_ci	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa1, 0x02, 0xff);
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	return 0;
22562306a36Sopenharmony_ci}
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ciconst struct x86_dev_info lenovo_yogabook_x90_info __initconst = {
22862306a36Sopenharmony_ci	.i2c_client_info = lenovo_yb1_x90_i2c_clients,
22962306a36Sopenharmony_ci	.i2c_client_count = ARRAY_SIZE(lenovo_yb1_x90_i2c_clients),
23062306a36Sopenharmony_ci	.pdev_info = lenovo_yb1_x90_pdevs,
23162306a36Sopenharmony_ci	.pdev_count = ARRAY_SIZE(lenovo_yb1_x90_pdevs),
23262306a36Sopenharmony_ci	.serdev_info = lenovo_yb1_x90_serdevs,
23362306a36Sopenharmony_ci	.serdev_count = ARRAY_SIZE(lenovo_yb1_x90_serdevs),
23462306a36Sopenharmony_ci	.gpio_button = &lenovo_yb1_x90_lid,
23562306a36Sopenharmony_ci	.gpio_button_count = 1,
23662306a36Sopenharmony_ci	.gpiod_lookup_tables = lenovo_yb1_x90_gpios,
23762306a36Sopenharmony_ci	.init = lenovo_yb1_x90_init,
23862306a36Sopenharmony_ci};
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci/* Lenovo Yoga Book X91F/L Windows tablet needs manual instantiation of the fg client */
24162306a36Sopenharmony_cistatic const struct x86_i2c_client_info lenovo_yogabook_x91_i2c_clients[] __initconst = {
24262306a36Sopenharmony_ci	{
24362306a36Sopenharmony_ci		/* BQ27542 fuel-gauge */
24462306a36Sopenharmony_ci		.board_info = {
24562306a36Sopenharmony_ci			.type = "bq27542",
24662306a36Sopenharmony_ci			.addr = 0x55,
24762306a36Sopenharmony_ci			.dev_name = "bq27542",
24862306a36Sopenharmony_ci			.swnode = &fg_bq25890_supply_node,
24962306a36Sopenharmony_ci		},
25062306a36Sopenharmony_ci		.adapter_path = "\\_SB_.PCI0.I2C1",
25162306a36Sopenharmony_ci	},
25262306a36Sopenharmony_ci};
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ciconst struct x86_dev_info lenovo_yogabook_x91_info __initconst = {
25562306a36Sopenharmony_ci	.i2c_client_info = lenovo_yogabook_x91_i2c_clients,
25662306a36Sopenharmony_ci	.i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x91_i2c_clients),
25762306a36Sopenharmony_ci};
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci/* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */
26062306a36Sopenharmony_cistatic const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
26162306a36Sopenharmony_ci	PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1),
26262306a36Sopenharmony_ci	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
26362306a36Sopenharmony_ci	PROPERTY_ENTRY_BOOL("omit-battery-class"),
26462306a36Sopenharmony_ci	PROPERTY_ENTRY_BOOL("disable-reset"),
26562306a36Sopenharmony_ci	{ }
26662306a36Sopenharmony_ci};
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_cistatic const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
26962306a36Sopenharmony_ci	.properties = lenovo_yoga_tab2_830_1050_bq24190_props,
27062306a36Sopenharmony_ci};
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_cistatic const struct x86_gpio_button lenovo_yoga_tab2_830_1050_lid __initconst = {
27362306a36Sopenharmony_ci	.button = {
27462306a36Sopenharmony_ci		.code = SW_LID,
27562306a36Sopenharmony_ci		.active_low = true,
27662306a36Sopenharmony_ci		.desc = "lid_sw",
27762306a36Sopenharmony_ci		.type = EV_SW,
27862306a36Sopenharmony_ci		.wakeup = true,
27962306a36Sopenharmony_ci		.debounce_interval = 50,
28062306a36Sopenharmony_ci	},
28162306a36Sopenharmony_ci	.chip = "INT33FC:02",
28262306a36Sopenharmony_ci	.pin = 26,
28362306a36Sopenharmony_ci};
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci/* This gets filled by lenovo_yoga_tab2_830_1050_init() */
28662306a36Sopenharmony_cistatic struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_cistatic struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initdata = {
28962306a36Sopenharmony_ci	{
29062306a36Sopenharmony_ci		/*
29162306a36Sopenharmony_ci		 * This must be the first entry because lenovo_yoga_tab2_830_1050_init()
29262306a36Sopenharmony_ci		 * may update its swnode. LSM303DA accelerometer + magnetometer.
29362306a36Sopenharmony_ci		 */
29462306a36Sopenharmony_ci		.board_info = {
29562306a36Sopenharmony_ci			.type = "lsm303d",
29662306a36Sopenharmony_ci			.addr = 0x1d,
29762306a36Sopenharmony_ci			.dev_name = "lsm303d",
29862306a36Sopenharmony_ci		},
29962306a36Sopenharmony_ci		.adapter_path = "\\_SB_.I2C5",
30062306a36Sopenharmony_ci	}, {
30162306a36Sopenharmony_ci		/* AL3320A ambient light sensor */
30262306a36Sopenharmony_ci		.board_info = {
30362306a36Sopenharmony_ci			.type = "al3320a",
30462306a36Sopenharmony_ci			.addr = 0x1c,
30562306a36Sopenharmony_ci			.dev_name = "al3320a",
30662306a36Sopenharmony_ci		},
30762306a36Sopenharmony_ci		.adapter_path = "\\_SB_.I2C5",
30862306a36Sopenharmony_ci	}, {
30962306a36Sopenharmony_ci		/* bq24292i battery charger */
31062306a36Sopenharmony_ci		.board_info = {
31162306a36Sopenharmony_ci			.type = "bq24190",
31262306a36Sopenharmony_ci			.addr = 0x6b,
31362306a36Sopenharmony_ci			.dev_name = "bq24292i",
31462306a36Sopenharmony_ci			.swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
31562306a36Sopenharmony_ci			.platform_data = &bq24190_pdata,
31662306a36Sopenharmony_ci		},
31762306a36Sopenharmony_ci		.adapter_path = "\\_SB_.I2C1",
31862306a36Sopenharmony_ci		.irq_data = {
31962306a36Sopenharmony_ci			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
32062306a36Sopenharmony_ci			.chip = "INT33FC:02",
32162306a36Sopenharmony_ci			.index = 2,
32262306a36Sopenharmony_ci			.trigger = ACPI_EDGE_SENSITIVE,
32362306a36Sopenharmony_ci			.polarity = ACPI_ACTIVE_HIGH,
32462306a36Sopenharmony_ci		},
32562306a36Sopenharmony_ci	}, {
32662306a36Sopenharmony_ci		/* BQ27541 fuel-gauge */
32762306a36Sopenharmony_ci		.board_info = {
32862306a36Sopenharmony_ci			.type = "bq27541",
32962306a36Sopenharmony_ci			.addr = 0x55,
33062306a36Sopenharmony_ci			.dev_name = "bq27541",
33162306a36Sopenharmony_ci			.swnode = &fg_bq24190_supply_node,
33262306a36Sopenharmony_ci		},
33362306a36Sopenharmony_ci		.adapter_path = "\\_SB_.I2C1",
33462306a36Sopenharmony_ci	}, {
33562306a36Sopenharmony_ci		/* Synaptics RMI touchscreen */
33662306a36Sopenharmony_ci		.board_info = {
33762306a36Sopenharmony_ci			.type = "rmi4_i2c",
33862306a36Sopenharmony_ci			.addr = 0x38,
33962306a36Sopenharmony_ci			.dev_name = "rmi4_i2c",
34062306a36Sopenharmony_ci			.platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
34162306a36Sopenharmony_ci		},
34262306a36Sopenharmony_ci		.adapter_path = "\\_SB_.I2C6",
34362306a36Sopenharmony_ci		.irq_data = {
34462306a36Sopenharmony_ci			.type = X86_ACPI_IRQ_TYPE_APIC,
34562306a36Sopenharmony_ci			.index = 0x45,
34662306a36Sopenharmony_ci			.trigger = ACPI_EDGE_SENSITIVE,
34762306a36Sopenharmony_ci			.polarity = ACPI_ACTIVE_HIGH,
34862306a36Sopenharmony_ci		},
34962306a36Sopenharmony_ci	}, {
35062306a36Sopenharmony_ci		/* LP8557 Backlight controller */
35162306a36Sopenharmony_ci		.board_info = {
35262306a36Sopenharmony_ci			.type = "lp8557",
35362306a36Sopenharmony_ci			.addr = 0x2c,
35462306a36Sopenharmony_ci			.dev_name = "lp8557",
35562306a36Sopenharmony_ci			.platform_data = &lenovo_lp8557_pdata,
35662306a36Sopenharmony_ci		},
35762306a36Sopenharmony_ci		.adapter_path = "\\_SB_.I2C3",
35862306a36Sopenharmony_ci	},
35962306a36Sopenharmony_ci};
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_cistatic struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
36262306a36Sopenharmony_ci	.dev_id = "intel-int3496",
36362306a36Sopenharmony_ci	.table = {
36462306a36Sopenharmony_ci		GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
36562306a36Sopenharmony_ci		GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
36662306a36Sopenharmony_ci		{ }
36762306a36Sopenharmony_ci	},
36862306a36Sopenharmony_ci};
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci#define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_cistatic struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = {
37362306a36Sopenharmony_ci	.dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME,
37462306a36Sopenharmony_ci	.table = {
37562306a36Sopenharmony_ci		GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH),
37662306a36Sopenharmony_ci		GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH),
37762306a36Sopenharmony_ci		GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
37862306a36Sopenharmony_ci		GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW),
37962306a36Sopenharmony_ci		{ }
38062306a36Sopenharmony_ci	},
38162306a36Sopenharmony_ci};
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_cistatic struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = {
38462306a36Sopenharmony_ci	&lenovo_yoga_tab2_830_1050_int3496_gpios,
38562306a36Sopenharmony_ci	&lenovo_yoga_tab2_830_1050_codec_gpios,
38662306a36Sopenharmony_ci	NULL
38762306a36Sopenharmony_ci};
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_cistatic int __init lenovo_yoga_tab2_830_1050_init(void);
39062306a36Sopenharmony_cistatic void lenovo_yoga_tab2_830_1050_exit(void);
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ciconst struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initconst = {
39362306a36Sopenharmony_ci	.i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
39462306a36Sopenharmony_ci	.i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients),
39562306a36Sopenharmony_ci	.pdev_info = int3496_pdevs,
39662306a36Sopenharmony_ci	.pdev_count = 1,
39762306a36Sopenharmony_ci	.gpio_button = &lenovo_yoga_tab2_830_1050_lid,
39862306a36Sopenharmony_ci	.gpio_button_count = 1,
39962306a36Sopenharmony_ci	.gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios,
40062306a36Sopenharmony_ci	.bat_swnode = &generic_lipo_hv_4v35_battery_node,
40162306a36Sopenharmony_ci	.modules = bq24190_modules,
40262306a36Sopenharmony_ci	.init = lenovo_yoga_tab2_830_1050_init,
40362306a36Sopenharmony_ci	.exit = lenovo_yoga_tab2_830_1050_exit,
40462306a36Sopenharmony_ci};
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci/*
40762306a36Sopenharmony_ci * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
40862306a36Sopenharmony_ci * mainboard, but the 830 uses a portrait LCD panel with a landscape touchscreen,
40962306a36Sopenharmony_ci * requiring the touchscreen driver to adjust the touch-coords to match the LCD.
41062306a36Sopenharmony_ci * And requiring the accelerometer to have a mount-matrix set to correct for
41162306a36Sopenharmony_ci * the 90° rotation of the LCD vs the frame.
41262306a36Sopenharmony_ci */
41362306a36Sopenharmony_cistatic const char * const lenovo_yoga_tab2_830_lms303d_mount_matrix[] = {
41462306a36Sopenharmony_ci	"0", "1", "0",
41562306a36Sopenharmony_ci	"-1", "0", "0",
41662306a36Sopenharmony_ci	"0", "0", "1"
41762306a36Sopenharmony_ci};
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_cistatic const struct property_entry lenovo_yoga_tab2_830_lms303d_props[] = {
42062306a36Sopenharmony_ci	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_830_lms303d_mount_matrix),
42162306a36Sopenharmony_ci	{ }
42262306a36Sopenharmony_ci};
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_cistatic const struct software_node lenovo_yoga_tab2_830_lms303d_node = {
42562306a36Sopenharmony_ci	.properties = lenovo_yoga_tab2_830_lms303d_props,
42662306a36Sopenharmony_ci};
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_cistatic int __init lenovo_yoga_tab2_830_1050_init_touchscreen(void)
42962306a36Sopenharmony_ci{
43062306a36Sopenharmony_ci	struct gpio_desc *gpiod;
43162306a36Sopenharmony_ci	int ret;
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	/* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
43462306a36Sopenharmony_ci	ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, &gpiod);
43562306a36Sopenharmony_ci	if (ret)
43662306a36Sopenharmony_ci		return ret;
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci	ret = gpiod_get_value_cansleep(gpiod);
43962306a36Sopenharmony_ci	if (ret) {
44062306a36Sopenharmony_ci		pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
44162306a36Sopenharmony_ci	} else {
44262306a36Sopenharmony_ci		pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
44362306a36Sopenharmony_ci		lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
44462306a36Sopenharmony_ci		lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
44562306a36Sopenharmony_ci		lenovo_yoga_tab2_830_1050_i2c_clients[0].board_info.swnode =
44662306a36Sopenharmony_ci			&lenovo_yoga_tab2_830_lms303d_node;
44762306a36Sopenharmony_ci	}
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	return 0;
45062306a36Sopenharmony_ci}
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci/* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
45362306a36Sopenharmony_cistatic const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
45462306a36Sopenharmony_ci	PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
45562306a36Sopenharmony_ci			  "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_cistatic struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
45862306a36Sopenharmony_cistatic struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_cistatic int __init lenovo_yoga_tab2_830_1050_init_codec(void)
46162306a36Sopenharmony_ci{
46262306a36Sopenharmony_ci	struct device *codec_dev;
46362306a36Sopenharmony_ci	struct pinctrl *pinctrl;
46462306a36Sopenharmony_ci	int ret;
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci	codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
46762306a36Sopenharmony_ci					    LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
46862306a36Sopenharmony_ci	if (!codec_dev) {
46962306a36Sopenharmony_ci		pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
47062306a36Sopenharmony_ci		return -ENODEV;
47162306a36Sopenharmony_ci	}
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci	ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
47462306a36Sopenharmony_ci	if (ret)
47562306a36Sopenharmony_ci		goto err_put_device;
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci	pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
47862306a36Sopenharmony_ci	if (IS_ERR(pinctrl)) {
47962306a36Sopenharmony_ci		ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
48062306a36Sopenharmony_ci		goto err_unregister_mappings;
48162306a36Sopenharmony_ci	}
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci	/* We're done with the codec_dev now */
48462306a36Sopenharmony_ci	put_device(codec_dev);
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci	lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
48762306a36Sopenharmony_ci	return 0;
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_cierr_unregister_mappings:
49062306a36Sopenharmony_ci	pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
49162306a36Sopenharmony_cierr_put_device:
49262306a36Sopenharmony_ci	put_device(codec_dev);
49362306a36Sopenharmony_ci	return ret;
49462306a36Sopenharmony_ci}
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci/*
49762306a36Sopenharmony_ci * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off
49862306a36Sopenharmony_ci * gets used as pm_power_off handler. This causes "poweroff" on these tablets
49962306a36Sopenharmony_ci * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice*
50062306a36Sopenharmony_ci * followed by a normal 3 second press to recover. Avoid this by doing an EFI
50162306a36Sopenharmony_ci * poweroff instead.
50262306a36Sopenharmony_ci */
50362306a36Sopenharmony_cistatic int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
50462306a36Sopenharmony_ci{
50562306a36Sopenharmony_ci	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	return NOTIFY_DONE;
50862306a36Sopenharmony_ci}
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_cistatic int __init lenovo_yoga_tab2_830_1050_init(void)
51162306a36Sopenharmony_ci{
51262306a36Sopenharmony_ci	int ret;
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	ret = lenovo_yoga_tab2_830_1050_init_touchscreen();
51562306a36Sopenharmony_ci	if (ret)
51662306a36Sopenharmony_ci		return ret;
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	ret = lenovo_yoga_tab2_830_1050_init_codec();
51962306a36Sopenharmony_ci	if (ret)
52062306a36Sopenharmony_ci		return ret;
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	/* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */
52362306a36Sopenharmony_ci	lenovo_yoga_tab2_830_1050_sys_off_handler =
52462306a36Sopenharmony_ci		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
52562306a36Sopenharmony_ci					 lenovo_yoga_tab2_830_1050_power_off, NULL);
52662306a36Sopenharmony_ci	if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
52762306a36Sopenharmony_ci		return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci	return 0;
53062306a36Sopenharmony_ci}
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_cistatic void lenovo_yoga_tab2_830_1050_exit(void)
53362306a36Sopenharmony_ci{
53462306a36Sopenharmony_ci	unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	if (lenovo_yoga_tab2_830_1050_codec_pinctrl) {
53762306a36Sopenharmony_ci		pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
53862306a36Sopenharmony_ci		pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
53962306a36Sopenharmony_ci	}
54062306a36Sopenharmony_ci}
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci/* Lenovo Yoga Tab 3 Pro YT3-X90F */
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci/*
54562306a36Sopenharmony_ci * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers,
54662306a36Sopenharmony_ci * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c.
54762306a36Sopenharmony_ci */
54862306a36Sopenharmony_cistatic const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" };
54962306a36Sopenharmony_cistatic const char * const bq25890_1_psy[] = { "bq25890-charger-1" };
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_cistatic const struct property_entry fg_bq25890_1_supply_props[] = {
55262306a36Sopenharmony_ci	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy),
55362306a36Sopenharmony_ci	{ }
55462306a36Sopenharmony_ci};
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_cistatic const struct software_node fg_bq25890_1_supply_node = {
55762306a36Sopenharmony_ci	.properties = fg_bq25890_1_supply_props,
55862306a36Sopenharmony_ci};
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci/* bq25892 charger settings for the flat lipo battery behind the screen */
56162306a36Sopenharmony_cistatic const struct property_entry lenovo_yt3_bq25892_0_props[] = {
56262306a36Sopenharmony_ci	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers),
56362306a36Sopenharmony_ci	PROPERTY_ENTRY_STRING("linux,power-supply-name", "bq25892-second-chrg"),
56462306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40),
56562306a36Sopenharmony_ci	PROPERTY_ENTRY_BOOL("linux,skip-reset"),
56662306a36Sopenharmony_ci	/* Values taken from Android Factory Image */
56762306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("ti,charge-current", 2048000),
56862306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
56962306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("ti,termination-current", 128000),
57062306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
57162306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000),
57262306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
57362306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("ti,boost-max-current", 500000),
57462306a36Sopenharmony_ci	PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
57562306a36Sopenharmony_ci	{ }
57662306a36Sopenharmony_ci};
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_cistatic const struct software_node lenovo_yt3_bq25892_0_node = {
57962306a36Sopenharmony_ci	.properties = lenovo_yt3_bq25892_0_props,
58062306a36Sopenharmony_ci};
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_cistatic const struct property_entry lenovo_yt3_hideep_ts_props[] = {
58362306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
58462306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("touchscreen-size-y", 2560),
58562306a36Sopenharmony_ci	PROPERTY_ENTRY_U32("touchscreen-max-pressure", 255),
58662306a36Sopenharmony_ci	{ }
58762306a36Sopenharmony_ci};
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_cistatic const struct software_node lenovo_yt3_hideep_ts_node = {
59062306a36Sopenharmony_ci	.properties = lenovo_yt3_hideep_ts_props,
59162306a36Sopenharmony_ci};
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_cistatic const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
59462306a36Sopenharmony_ci	{
59562306a36Sopenharmony_ci		/* bq27500 fuel-gauge for the flat lipo battery behind the screen */
59662306a36Sopenharmony_ci		.board_info = {
59762306a36Sopenharmony_ci			.type = "bq27500",
59862306a36Sopenharmony_ci			.addr = 0x55,
59962306a36Sopenharmony_ci			.dev_name = "bq27500_0",
60062306a36Sopenharmony_ci			.swnode = &fg_bq25890_supply_node,
60162306a36Sopenharmony_ci		},
60262306a36Sopenharmony_ci		.adapter_path = "\\_SB_.PCI0.I2C1",
60362306a36Sopenharmony_ci	}, {
60462306a36Sopenharmony_ci		/* bq25892 charger for the flat lipo battery behind the screen */
60562306a36Sopenharmony_ci		.board_info = {
60662306a36Sopenharmony_ci			.type = "bq25892",
60762306a36Sopenharmony_ci			.addr = 0x6b,
60862306a36Sopenharmony_ci			.dev_name = "bq25892_0",
60962306a36Sopenharmony_ci			.swnode = &lenovo_yt3_bq25892_0_node,
61062306a36Sopenharmony_ci		},
61162306a36Sopenharmony_ci		.adapter_path = "\\_SB_.PCI0.I2C1",
61262306a36Sopenharmony_ci		.irq_data = {
61362306a36Sopenharmony_ci			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
61462306a36Sopenharmony_ci			.chip = "INT33FF:01",
61562306a36Sopenharmony_ci			.index = 5,
61662306a36Sopenharmony_ci			.trigger = ACPI_EDGE_SENSITIVE,
61762306a36Sopenharmony_ci			.polarity = ACPI_ACTIVE_LOW,
61862306a36Sopenharmony_ci		},
61962306a36Sopenharmony_ci	}, {
62062306a36Sopenharmony_ci		/* bq27500 fuel-gauge for the round li-ion cells in the hinge */
62162306a36Sopenharmony_ci		.board_info = {
62262306a36Sopenharmony_ci			.type = "bq27500",
62362306a36Sopenharmony_ci			.addr = 0x55,
62462306a36Sopenharmony_ci			.dev_name = "bq27500_1",
62562306a36Sopenharmony_ci			.swnode = &fg_bq25890_1_supply_node,
62662306a36Sopenharmony_ci		},
62762306a36Sopenharmony_ci		.adapter_path = "\\_SB_.PCI0.I2C2",
62862306a36Sopenharmony_ci	}, {
62962306a36Sopenharmony_ci		/* HiDeep IST520E Touchscreen */
63062306a36Sopenharmony_ci		.board_info = {
63162306a36Sopenharmony_ci			.type = "hideep_ts",
63262306a36Sopenharmony_ci			.addr = 0x6c,
63362306a36Sopenharmony_ci			.dev_name = "hideep_ts",
63462306a36Sopenharmony_ci			.swnode = &lenovo_yt3_hideep_ts_node,
63562306a36Sopenharmony_ci		},
63662306a36Sopenharmony_ci		.adapter_path = "\\_SB_.PCI0.I2C6",
63762306a36Sopenharmony_ci		.irq_data = {
63862306a36Sopenharmony_ci			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
63962306a36Sopenharmony_ci			.chip = "INT33FF:03",
64062306a36Sopenharmony_ci			.index = 77,
64162306a36Sopenharmony_ci			.trigger = ACPI_LEVEL_SENSITIVE,
64262306a36Sopenharmony_ci			.polarity = ACPI_ACTIVE_LOW,
64362306a36Sopenharmony_ci		},
64462306a36Sopenharmony_ci	}, {
64562306a36Sopenharmony_ci		/* LP8557 Backlight controller */
64662306a36Sopenharmony_ci		.board_info = {
64762306a36Sopenharmony_ci			.type = "lp8557",
64862306a36Sopenharmony_ci			.addr = 0x2c,
64962306a36Sopenharmony_ci			.dev_name = "lp8557",
65062306a36Sopenharmony_ci			.platform_data = &lenovo_lp8557_pdata,
65162306a36Sopenharmony_ci		},
65262306a36Sopenharmony_ci		.adapter_path = "\\_SB_.PCI0.I2C1",
65362306a36Sopenharmony_ci	}
65462306a36Sopenharmony_ci};
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_cistatic int __init lenovo_yt3_init(void)
65762306a36Sopenharmony_ci{
65862306a36Sopenharmony_ci	struct gpio_desc *gpiod;
65962306a36Sopenharmony_ci	int ret;
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci	/*
66262306a36Sopenharmony_ci	 * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins
66362306a36Sopenharmony_ci	 * connected to GPIOs, rather then having them hardwired to the correct
66462306a36Sopenharmony_ci	 * values as is normally done.
66562306a36Sopenharmony_ci	 *
66662306a36Sopenharmony_ci	 * The bq25890_charger driver controls these through I2C, but this only
66762306a36Sopenharmony_ci	 * works if not overridden by the pins. Set these pins here:
66862306a36Sopenharmony_ci	 * 1. Set /CE to 0 to allow charging.
66962306a36Sopenharmony_ci	 * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of
67062306a36Sopenharmony_ci	 *    the main "bq25892_1" charger is used when necessary.
67162306a36Sopenharmony_ci	 */
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ci	/* /CE pin */
67462306a36Sopenharmony_ci	ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, &gpiod);
67562306a36Sopenharmony_ci	if (ret < 0)
67662306a36Sopenharmony_ci		return ret;
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci	/*
67962306a36Sopenharmony_ci	 * The gpio_desc returned by x86_android_tablet_get_gpiod() is a "raw"
68062306a36Sopenharmony_ci	 * gpio_desc, that is there is no way to pass lookup-flags like
68162306a36Sopenharmony_ci	 * GPIO_ACTIVE_LOW. Set the GPIO to 0 here to enable charging since
68262306a36Sopenharmony_ci	 * the /CE pin is active-low, but not marked as such in the gpio_desc.
68362306a36Sopenharmony_ci	 */
68462306a36Sopenharmony_ci	gpiod_set_value(gpiod, 0);
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci	/* OTG pin */
68762306a36Sopenharmony_ci	ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, &gpiod);
68862306a36Sopenharmony_ci	if (ret < 0)
68962306a36Sopenharmony_ci		return ret;
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_ci	gpiod_set_value(gpiod, 0);
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci	/* Enable the regulators used by the touchscreen */
69462306a36Sopenharmony_ci	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
69562306a36Sopenharmony_ci	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	return 0;
69862306a36Sopenharmony_ci}
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_cistatic struct gpiod_lookup_table lenovo_yt3_hideep_gpios = {
70162306a36Sopenharmony_ci	.dev_id = "i2c-hideep_ts",
70262306a36Sopenharmony_ci	.table = {
70362306a36Sopenharmony_ci		GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
70462306a36Sopenharmony_ci		{ }
70562306a36Sopenharmony_ci	},
70662306a36Sopenharmony_ci};
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_cistatic struct gpiod_lookup_table * const lenovo_yt3_gpios[] = {
70962306a36Sopenharmony_ci	&lenovo_yt3_hideep_gpios,
71062306a36Sopenharmony_ci	NULL
71162306a36Sopenharmony_ci};
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ciconst struct x86_dev_info lenovo_yt3_info __initconst = {
71462306a36Sopenharmony_ci	.i2c_client_info = lenovo_yt3_i2c_clients,
71562306a36Sopenharmony_ci	.i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients),
71662306a36Sopenharmony_ci	.gpiod_lookup_tables = lenovo_yt3_gpios,
71762306a36Sopenharmony_ci	.init = lenovo_yt3_init,
71862306a36Sopenharmony_ci};
719