File Index
Files and directories
Sign in
FILE

lenovo.c

File preview with syntax highlighting.

linux-6.19.14/drivers/platform/x86/x86-android-tablets/lenovo.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Board info for Lenovo X86 tablets which ship with Android as the factory image
   4 * and which have broken DSDT tables. The factory kernels shipped on these
   5 * devices typically have a bunch of things hardcoded, rather than specified
   6 * in their DSDT.
   7 *
   8 * Copyright (C) 2021-2023 Hans de Goede <hansg@kernel.org>
   9 */
  10
  11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  12
  13#include <linux/efi.h>
  14#include <linux/gpio/machine.h>
  15#include <linux/gpio/property.h>
  16#include <linux/input-event-codes.h>
  17#include <linux/mfd/arizona/pdata.h>
  18#include <linux/mfd/arizona/registers.h>
  19#include <linux/mfd/intel_soc_pmic.h>
  20#include <linux/pinctrl/consumer.h>
  21#include <linux/pinctrl/machine.h>
  22#include <linux/platform_data/lp855x.h>
  23#include <linux/platform_device.h>
  24#include <linux/power/bq24190_charger.h>
  25#include <linux/reboot.h>
  26#include <linux/rmi.h>
  27#include <linux/spi/spi.h>
  28
  29#include "shared-psy-info.h"
  30#include "x86-android-tablets.h"
  31
  32/*
  33 * Various Lenovo models use a TI LP8557 LED backlight controller with its PWM
  34 * input connected to a PWM output coming from the LCD panel's controller.
  35 * The Android kernels have a hack in the i915 driver to write a non-standard
  36 * panel specific DSI register to set the duty-cycle of the LCD's PWM output.
  37 *
  38 * To avoid having to have a similar hack in the mainline kernel program the
  39 * LP8557 to directly set the level and use the lp855x_bl driver for control.
  40 *
  41 * The LP8557 can either be configured to multiply its PWM input and
  42 * the I2C register set level (requiring both to be at 100% for 100% output);
  43 * or to only take the I2C register set level into account.
  44 *
  45 * Multiplying the 2 levels is useful because this will turn off the backlight
  46 * when the panel goes off and turns off its PWM output.
  47 *
  48 * But on some models the panel's PWM output defaults to a duty-cycle of
  49 * much less then 100%, severely limiting max brightness. In this case
  50 * the LP8557 should be configured to only take the I2C register into
  51 * account and the i915 driver must turn off the panel and the backlight
  52 * separately using e.g. VBT MIPI sequences to turn off the backlight.
  53 */
  54static struct lp855x_platform_data lenovo_lp8557_pwm_and_reg_pdata = {
  55	.device_control = 0x86,
  56	.initial_brightness = 128,
  57};
  58
  59static struct lp855x_platform_data lenovo_lp8557_reg_only_pdata = {
  60	.device_control = 0x85,
  61	.initial_brightness = 128,
  62};
  63
  64static const struct software_node arizona_gpiochip_node = {
  65	.name = "arizona",
  66};
  67
  68static const struct software_node crystalcove_gpiochip_node = {
  69	.name = "gpio_crystalcove",
  70};
  71
  72/* Lenovo Yoga Book X90F / X90L's Android factory image has everything hardcoded */
  73
  74static const struct property_entry lenovo_yb1_x90_goodix_props[] = {
  75	PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[1], 53, GPIO_ACTIVE_HIGH),
  76	PROPERTY_ENTRY_GPIO("irq-gpios", &cherryview_gpiochip_nodes[1], 56, GPIO_ACTIVE_HIGH),
  77	{ }
  78};
  79
  80static const struct software_node lenovo_yb1_x90_goodix_node = {
  81	.properties = lenovo_yb1_x90_goodix_props,
  82};
  83
  84static const struct property_entry lenovo_yb1_x90_wacom_props[] = {
  85	PROPERTY_ENTRY_U32("hid-descr-addr", 0x0001),
  86	PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 150),
  87	PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 82, GPIO_ACTIVE_LOW),
  88	{ }
  89};
  90
  91static const struct software_node lenovo_yb1_x90_wacom_node = {
  92	.properties = lenovo_yb1_x90_wacom_props,
  93};
  94
  95/*
  96 * The HiDeep IST940E touchscreen comes up in I2C-HID mode. The native protocol
  97 * reports ABS_MT_PRESSURE and ABS_MT_TOUCH_MAJOR which are not reported in HID
  98 * mode, so using native mode is preferred.
  99 * It could alternatively be used in HID mode by changing the properties to:
 100 *	PROPERTY_ENTRY_U32("hid-descr-addr", 0x0020),
 101 *	PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
 102 * and changing board_info.type to "hid-over-i2c".
 103 */
 104static const struct property_entry lenovo_yb1_x90_hideep_ts_props[] = {
 105	PROPERTY_ENTRY_U32("touchscreen-size-x", 1200),
 106	PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
 107	PROPERTY_ENTRY_U32("touchscreen-max-pressure", 16384),
 108	PROPERTY_ENTRY_BOOL("hideep,force-native-protocol"),
 109	PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 7, GPIO_ACTIVE_LOW),
 110	{ }
 111};
 112
 113static const struct software_node lenovo_yb1_x90_hideep_ts_node = {
 114	.properties = lenovo_yb1_x90_hideep_ts_props,
 115};
 116
 117static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst = {
 118	{
 119		/* BQ27542 fuel-gauge */
 120		.board_info = {
 121			.type = "bq27542",
 122			.addr = 0x55,
 123			.dev_name = "bq27542",
 124			.swnode = &fg_bq25890_supply_node,
 125		},
 126		.adapter_path = "\\_SB_.PCI0.I2C1",
 127	}, {
 128		/* Goodix Touchscreen in keyboard half */
 129		.board_info = {
 130			.type = "GDIX1001:00",
 131			.addr = 0x14,
 132			.dev_name = "goodix_ts",
 133			.swnode = &lenovo_yb1_x90_goodix_node,
 134		},
 135		.adapter_path = "\\_SB_.PCI0.I2C2",
 136		.irq_data = {
 137			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 138			.chip = "INT33FF:01",
 139			.index = 56,
 140			.trigger = ACPI_EDGE_SENSITIVE,
 141			.polarity = ACPI_ACTIVE_LOW,
 142			.con_id = "goodix_ts_irq",
 143			.free_gpio = true,
 144		},
 145	}, {
 146		/* Wacom Digitizer in keyboard half */
 147		.board_info = {
 148			.type = "hid-over-i2c",
 149			.addr = 0x09,
 150			.dev_name = "wacom",
 151			.swnode = &lenovo_yb1_x90_wacom_node,
 152		},
 153		.adapter_path = "\\_SB_.PCI0.I2C4",
 154		.irq_data = {
 155			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 156			.chip = "INT33FF:01",
 157			.index = 49,
 158			.trigger = ACPI_LEVEL_SENSITIVE,
 159			.polarity = ACPI_ACTIVE_LOW,
 160			.con_id = "wacom_irq",
 161		},
 162	}, {
 163		/* LP8557 Backlight controller */
 164		.board_info = {
 165			.type = "lp8557",
 166			.addr = 0x2c,
 167			.dev_name = "lp8557",
 168			.platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
 169		},
 170		.adapter_path = "\\_SB_.PCI0.I2C4",
 171	}, {
 172		/* HiDeep IST940E Touchscreen in display half */
 173		.board_info = {
 174			.type = "hideep_ts",
 175			.addr = 0x6c,
 176			.dev_name = "hideep_ts",
 177			.swnode = &lenovo_yb1_x90_hideep_ts_node,
 178		},
 179		.adapter_path = "\\_SB_.PCI0.I2C6",
 180		.irq_data = {
 181			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 182			.chip = "INT33FF:03",
 183			.index = 77,
 184			.trigger = ACPI_LEVEL_SENSITIVE,
 185			.polarity = ACPI_ACTIVE_LOW,
 186			.con_id = "hideep_ts_irq",
 187		},
 188	},
 189};
 190
 191static const struct platform_device_info lenovo_yb1_x90_pdevs[] __initconst = {
 192	{
 193		.name = "yogabook-touch-kbd-digitizer-switch",
 194		.id = PLATFORM_DEVID_NONE,
 195	},
 196};
 197
 198/*
 199 * DSDT says UART path is "\\_SB.PCIO.URT1" with a letter 'O' instead of
 200 * the number '0' add the link manually.
 201 */
 202static const struct x86_serdev_info lenovo_yb1_x90_serdevs[] __initconst = {
 203	{
 204		.ctrl.acpi.hid = "8086228A",
 205		.ctrl.acpi.uid = "1",
 206		.ctrl_devname = "serial0",
 207		.serdev_hid = "BCM2E1A",
 208	},
 209};
 210
 211/*
 212 * Software node attached to gpio-keys device representing the LID and
 213 * serving as a parent to software nodes representing individual keys/buttons
 214 * as required by the device tree binding.
 215 */
 216static const struct software_node lenovo_lid_gpio_keys_node = {
 217	.name = "lid_sw",
 218};
 219
 220static const struct property_entry lenovo_yb1_x90_lid_props[] = {
 221	PROPERTY_ENTRY_U32("linux,input-type", EV_SW),
 222	PROPERTY_ENTRY_U32("linux,code", SW_LID),
 223	PROPERTY_ENTRY_STRING("label", "lid_sw"),
 224	PROPERTY_ENTRY_GPIO("gpios", &cherryview_gpiochip_nodes[2], 19, GPIO_ACTIVE_LOW),
 225	PROPERTY_ENTRY_U32("debounce-interval", 50),
 226	PROPERTY_ENTRY_BOOL("wakeup-source"),
 227	{ }
 228};
 229
 230static const struct software_node lenovo_yb1_x90_lid_node = {
 231	.parent = &lenovo_lid_gpio_keys_node,
 232	.properties = lenovo_yb1_x90_lid_props,
 233};
 234
 235static const struct software_node *lenovo_yb1_x90_lid_swnodes[] = {
 236	&lenovo_lid_gpio_keys_node,
 237	&lenovo_yb1_x90_lid_node,
 238	NULL
 239};
 240
 241static int __init lenovo_yb1_x90_init(struct device *dev)
 242{
 243	/* Enable the regulators used by the touchscreens */
 244
 245	/* Vprog3B 3.0V used by the goodix touchscreen in the keyboard half */
 246	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
 247
 248	/* Vprog4D 3.0V used by the HiDeep touchscreen in the display half */
 249	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9f, 0x02, 0xff);
 250
 251	/* Vprog5A 1.8V used by the HiDeep touchscreen in the display half */
 252	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
 253
 254	/* Vprog5B 1.8V used by the goodix touchscreen in the keyboard half */
 255	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa1, 0x02, 0xff);
 256
 257	return 0;
 258}
 259
 260const struct x86_dev_info lenovo_yogabook_x90_info __initconst = {
 261	.i2c_client_info = lenovo_yb1_x90_i2c_clients,
 262	.i2c_client_count = ARRAY_SIZE(lenovo_yb1_x90_i2c_clients),
 263	.pdev_info = lenovo_yb1_x90_pdevs,
 264	.pdev_count = ARRAY_SIZE(lenovo_yb1_x90_pdevs),
 265	.serdev_info = lenovo_yb1_x90_serdevs,
 266	.serdev_count = ARRAY_SIZE(lenovo_yb1_x90_serdevs),
 267	.gpio_button_swnodes = lenovo_yb1_x90_lid_swnodes,
 268	.gpiochip_type = X86_GPIOCHIP_CHERRYVIEW,
 269	.init = lenovo_yb1_x90_init,
 270};
 271
 272/* Lenovo Yoga Book X91F/L Windows tablet needs manual instantiation of the fuel-gauge client */
 273static const struct x86_i2c_client_info lenovo_yogabook_x91_i2c_clients[] __initconst = {
 274	{
 275		/* BQ27542 fuel-gauge */
 276		.board_info = {
 277			.type = "bq27542",
 278			.addr = 0x55,
 279			.dev_name = "bq27542",
 280			.swnode = &fg_bq25890_supply_node,
 281		},
 282		.adapter_path = "\\_SB_.PCI0.I2C1",
 283	},
 284};
 285
 286const struct x86_dev_info lenovo_yogabook_x91_info __initconst = {
 287	.i2c_client_info = lenovo_yogabook_x91_i2c_clients,
 288	.i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x91_i2c_clients),
 289};
 290
 291/* Lenovo Yoga Tablet 2 1050F/L's Android factory image has everything hardcoded */
 292static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
 293	PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1),
 294	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
 295	PROPERTY_ENTRY_BOOL("omit-battery-class"),
 296	PROPERTY_ENTRY_BOOL("disable-reset"),
 297	{ }
 298};
 299
 300static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
 301	.properties = lenovo_yoga_tab2_830_1050_bq24190_props,
 302};
 303
 304static const struct property_entry lenovo_yoga_tab2_830_1050_lid_props[] = {
 305	PROPERTY_ENTRY_U32("linux,input-type", EV_SW),
 306	PROPERTY_ENTRY_U32("linux,code", SW_LID),
 307	PROPERTY_ENTRY_STRING("label", "lid_sw"),
 308	PROPERTY_ENTRY_GPIO("gpios", &baytrail_gpiochip_nodes[2], 26, GPIO_ACTIVE_LOW),
 309	PROPERTY_ENTRY_U32("debounce-interval", 50),
 310	PROPERTY_ENTRY_BOOL("wakeup-source"),
 311	{ }
 312};
 313
 314static const struct software_node lenovo_yoga_tab2_830_1050_lid_node = {
 315	.parent = &lenovo_lid_gpio_keys_node,
 316	.properties = lenovo_yoga_tab2_830_1050_lid_props,
 317};
 318
 319static const struct software_node *lenovo_yoga_tab2_830_1050_lid_swnodes[] = {
 320	&lenovo_lid_gpio_keys_node,
 321	&lenovo_yoga_tab2_830_1050_lid_node,
 322	NULL
 323};
 324
 325/* This gets filled by lenovo_yoga_tab2_830_1050_init() */
 326static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
 327
 328static struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initdata = {
 329	{
 330		/*
 331		 * This must be the first entry because lenovo_yoga_tab2_830_1050_init()
 332		 * may update its swnode. LSM303DA accelerometer + magnetometer.
 333		 */
 334		.board_info = {
 335			.type = "lsm303d",
 336			.addr = 0x1d,
 337			.dev_name = "lsm303d",
 338		},
 339		.adapter_path = "\\_SB_.I2C5",
 340	}, {
 341		/* AL3320A ambient light sensor */
 342		.board_info = {
 343			.type = "al3320a",
 344			.addr = 0x1c,
 345			.dev_name = "al3320a",
 346		},
 347		.adapter_path = "\\_SB_.I2C5",
 348	}, {
 349		/* bq24292i battery charger */
 350		.board_info = {
 351			.type = "bq24190",
 352			.addr = 0x6b,
 353			.dev_name = "bq24292i",
 354			.swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
 355			.platform_data = &bq24190_pdata,
 356		},
 357		.adapter_path = "\\_SB_.I2C1",
 358		.irq_data = {
 359			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 360			.chip = "INT33FC:02",
 361			.index = 2,
 362			.trigger = ACPI_EDGE_SENSITIVE,
 363			.polarity = ACPI_ACTIVE_HIGH,
 364			.con_id = "bq24292i_irq",
 365		},
 366	}, {
 367		/* BQ27541 fuel-gauge */
 368		.board_info = {
 369			.type = "bq27541",
 370			.addr = 0x55,
 371			.dev_name = "bq27541",
 372			.swnode = &fg_bq24190_supply_node,
 373		},
 374		.adapter_path = "\\_SB_.I2C1",
 375	}, {
 376		/* Synaptics RMI touchscreen */
 377		.board_info = {
 378			.type = "rmi4_i2c",
 379			.addr = 0x38,
 380			.dev_name = "rmi4_i2c",
 381			.platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
 382		},
 383		.adapter_path = "\\_SB_.I2C6",
 384		.irq_data = {
 385			.type = X86_ACPI_IRQ_TYPE_APIC,
 386			.index = 0x45,
 387			.trigger = ACPI_EDGE_SENSITIVE,
 388			.polarity = ACPI_ACTIVE_HIGH,
 389		},
 390	}, {
 391		/* LP8557 Backlight controller */
 392		.board_info = {
 393			.type = "lp8557",
 394			.addr = 0x2c,
 395			.dev_name = "lp8557",
 396			.platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
 397		},
 398		.adapter_path = "\\_SB_.I2C3",
 399	},
 400};
 401
 402static const struct property_entry lenovo_yoga_tab2_830_1050_int3496_props[] __initconst = {
 403	PROPERTY_ENTRY_GPIO("mux-gpios", &baytrail_gpiochip_nodes[2], 1, GPIO_ACTIVE_LOW),
 404	PROPERTY_ENTRY_GPIO("id-gpios", &baytrail_gpiochip_nodes[2], 24, GPIO_ACTIVE_HIGH),
 405	{ }
 406};
 407
 408static const struct platform_device_info lenovo_yoga_tab2_830_1050_pdevs[] __initconst = {
 409	{
 410		/* For micro USB ID pin handling */
 411		.name = "intel-int3496",
 412		.id = PLATFORM_DEVID_NONE,
 413		.properties = lenovo_yoga_tab2_830_1050_int3496_props,
 414	},
 415};
 416
 417#define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
 418
 419static const struct property_entry lenovo_yoga_tab2_830_1050_wm1502_props[] = {
 420	PROPERTY_ENTRY_GPIO("reset-gpios",
 421			    &crystalcove_gpiochip_node, 3, GPIO_ACTIVE_HIGH),
 422	PROPERTY_ENTRY_GPIO("wlf,ldoena-gpios",
 423			    &baytrail_gpiochip_nodes[1], 23, GPIO_ACTIVE_HIGH),
 424	PROPERTY_ENTRY_GPIO("wlf,spkvdd-ena-gpios",
 425			    &arizona_gpiochip_node, 2, GPIO_ACTIVE_HIGH),
 426	PROPERTY_ENTRY_GPIO("wlf,micd-pol-gpios",
 427			    &arizona_gpiochip_node, 4, GPIO_ACTIVE_LOW),
 428	{ }
 429};
 430
 431static const struct software_node lenovo_yoga_tab2_830_1050_wm5102 = {
 432	.properties = lenovo_yoga_tab2_830_1050_wm1502_props,
 433};
 434
 435static const struct software_node *lenovo_yoga_tab2_830_1050_swnodes[] = {
 436	&crystalcove_gpiochip_node,
 437	&arizona_gpiochip_node,
 438	&lenovo_yoga_tab2_830_1050_wm5102,
 439	&generic_lipo_hv_4v35_battery_node,
 440	NULL
 441};
 442
 443static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev);
 444static void lenovo_yoga_tab2_830_1050_exit(void);
 445
 446static const char * const lenovo_yoga_tab2_modules[] __initconst = {
 447	"spi_pxa2xx_platform",	/* For the SPI codec device */
 448	"bq24190_charger",	/* For the Vbus regulator for int3496/lc824206xa */
 449	NULL
 450};
 451
 452const struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initconst = {
 453	.i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
 454	.i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients),
 455	.pdev_info = lenovo_yoga_tab2_830_1050_pdevs,
 456	.pdev_count = ARRAY_SIZE(lenovo_yoga_tab2_830_1050_pdevs),
 457	.gpio_button_swnodes = lenovo_yoga_tab2_830_1050_lid_swnodes,
 458	.swnode_group = lenovo_yoga_tab2_830_1050_swnodes,
 459	.modules = lenovo_yoga_tab2_modules,
 460	.gpiochip_type = X86_GPIOCHIP_BAYTRAIL,
 461	.init = lenovo_yoga_tab2_830_1050_init,
 462	.exit = lenovo_yoga_tab2_830_1050_exit,
 463};
 464
 465/*
 466 * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
 467 * mainboard, but the 830 uses a portrait LCD panel with a landscape touchscreen,
 468 * requiring the touchscreen driver to adjust the touch-coords to match the LCD.
 469 * And requiring the accelerometer to have a mount-matrix set to correct for
 470 * the 90° rotation of the LCD vs the frame.
 471 */
 472static const char * const lenovo_yoga_tab2_830_lms303d_mount_matrix[] = {
 473	"0", "1", "0",
 474	"-1", "0", "0",
 475	"0", "0", "1"
 476};
 477
 478static const struct property_entry lenovo_yoga_tab2_830_lms303d_props[] = {
 479	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_830_lms303d_mount_matrix),
 480	{ }
 481};
 482
 483static const struct software_node lenovo_yoga_tab2_830_lms303d_node = {
 484	.properties = lenovo_yoga_tab2_830_lms303d_props,
 485};
 486
 487static int __init lenovo_yoga_tab2_830_1050_init_touchscreen(void)
 488{
 489	struct gpio_desc *gpiod;
 490	int ret;
 491
 492	/* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
 493	ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, "yoga_bootstrap",
 494					   false, GPIOD_ASIS, &gpiod);
 495	if (ret)
 496		return ret;
 497
 498	ret = gpiod_get_value_cansleep(gpiod);
 499	if (ret) {
 500		pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
 501	} else {
 502		pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
 503		lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
 504		lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
 505		lenovo_yoga_tab2_830_1050_i2c_clients[0].board_info.swnode =
 506			&lenovo_yoga_tab2_830_lms303d_node;
 507	}
 508
 509	return 0;
 510}
 511
 512/* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
 513static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
 514	PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
 515			  "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
 516
 517static struct device *lenovo_yoga_tab2_830_1050_codec_dev;
 518static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
 519static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
 520
 521static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
 522{
 523	struct device *codec_dev;
 524	struct pinctrl *pinctrl;
 525	int ret;
 526
 527	codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
 528					    LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
 529	if (!codec_dev) {
 530		pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
 531		return -ENODEV;
 532	}
 533
 534	ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
 535	if (ret)
 536		goto err_put_device;
 537
 538	pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
 539	if (IS_ERR(pinctrl)) {
 540		ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
 541		goto err_unregister_mappings;
 542	}
 543
 544	ret = device_add_software_node(codec_dev, &lenovo_yoga_tab2_830_1050_wm5102);
 545	if (ret) {
 546		dev_err_probe(codec_dev, ret, "adding software node\n");
 547		goto err_put_pinctrl;
 548	}
 549
 550	lenovo_yoga_tab2_830_1050_codec_dev = codec_dev;
 551	lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
 552	return 0;
 553
 554err_put_pinctrl:
 555	pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
 556err_unregister_mappings:
 557	pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
 558err_put_device:
 559	put_device(codec_dev);
 560	return ret;
 561}
 562
 563/*
 564 * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off()
 565 * gets used as pm_power_off handler. This causes "poweroff" on these tablets
 566 * to hang hard. Requiring pressing the power button for 30 seconds *twice*
 567 * followed by a normal 3 second press to recover. Avoid this by doing an EFI
 568 * poweroff instead.
 569 */
 570static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
 571{
 572	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
 573
 574	return NOTIFY_DONE;
 575}
 576
 577static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev)
 578{
 579	int ret;
 580
 581	ret = lenovo_yoga_tab2_830_1050_init_touchscreen();
 582	if (ret)
 583		return ret;
 584
 585	ret = lenovo_yoga_tab2_830_1050_init_codec();
 586	if (ret)
 587		return ret;
 588
 589	/* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off() */
 590	lenovo_yoga_tab2_830_1050_sys_off_handler =
 591		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
 592					 lenovo_yoga_tab2_830_1050_power_off, NULL);
 593	if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
 594		return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
 595
 596	return 0;
 597}
 598
 599static void lenovo_yoga_tab2_830_1050_exit(void)
 600{
 601	unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
 602
 603	device_remove_software_node(lenovo_yoga_tab2_830_1050_codec_dev);
 604	pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
 605	pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
 606	put_device(lenovo_yoga_tab2_830_1050_codec_dev);
 607}
 608
 609/*
 610 * Lenovo Yoga Tablet 2 Pro 1380F/L
 611 *
 612 * The Lenovo Yoga Tablet 2 Pro 1380F/L mostly has the same design as the 830F/L
 613 * and the 1050F/L so this re-uses some of the handling for that from above.
 614 */
 615static const char * const lc824206xa_chg_det_psy[] = { "lc824206xa-charger-detect" };
 616
 617static const struct property_entry lenovo_yoga_tab2_1380_bq24190_props[] = {
 618	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lc824206xa_chg_det_psy),
 619	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
 620	PROPERTY_ENTRY_BOOL("omit-battery-class"),
 621	PROPERTY_ENTRY_BOOL("disable-reset"),
 622	{ }
 623};
 624
 625static const struct software_node lenovo_yoga_tab2_1380_bq24190_node = {
 626	.properties = lenovo_yoga_tab2_1380_bq24190_props,
 627};
 628
 629/* For enabling the bq24190 5V boost based on id-pin */
 630static struct regulator_consumer_supply lc824206xa_consumer = {
 631	.supply = "vbus",
 632	.dev_name = "i2c-lc824206xa",
 633};
 634
 635static const struct regulator_init_data lenovo_yoga_tab2_1380_bq24190_vbus_init_data = {
 636	.constraints = {
 637		.name = "bq24190_vbus",
 638		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
 639	},
 640	.consumer_supplies = &lc824206xa_consumer,
 641	.num_consumer_supplies = 1,
 642};
 643
 644static struct bq24190_platform_data lenovo_yoga_tab2_1380_bq24190_pdata = {
 645	.regulator_init_data = &lenovo_yoga_tab2_1380_bq24190_vbus_init_data,
 646};
 647
 648static const struct property_entry lenovo_yoga_tab2_1380_lc824206xa_props[] = {
 649	PROPERTY_ENTRY_BOOL("onnn,enable-miclr-for-dcp"),
 650	{ }
 651};
 652
 653static const struct software_node lenovo_yoga_tab2_1380_lc824206xa_node = {
 654	.properties = lenovo_yoga_tab2_1380_lc824206xa_props,
 655};
 656
 657static const char * const lenovo_yoga_tab2_1380_lms303d_mount_matrix[] = {
 658	"0", "-1", "0",
 659	"-1", "0", "0",
 660	"0", "0", "1"
 661};
 662
 663static const struct property_entry lenovo_yoga_tab2_1380_lms303d_props[] = {
 664	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_1380_lms303d_mount_matrix),
 665	{ }
 666};
 667
 668static const struct software_node lenovo_yoga_tab2_1380_lms303d_node = {
 669	.properties = lenovo_yoga_tab2_1380_lms303d_props,
 670};
 671
 672static const struct x86_i2c_client_info lenovo_yoga_tab2_1380_i2c_clients[] __initconst = {
 673	{
 674		/* BQ27541 fuel-gauge */
 675		.board_info = {
 676			.type = "bq27541",
 677			.addr = 0x55,
 678			.dev_name = "bq27541",
 679			.swnode = &fg_bq24190_supply_node,
 680		},
 681		.adapter_path = "\\_SB_.I2C1",
 682	}, {
 683		/* bq24292i battery charger */
 684		.board_info = {
 685			.type = "bq24190",
 686			.addr = 0x6b,
 687			.dev_name = "bq24292i",
 688			.swnode = &lenovo_yoga_tab2_1380_bq24190_node,
 689			.platform_data = &lenovo_yoga_tab2_1380_bq24190_pdata,
 690		},
 691		.adapter_path = "\\_SB_.I2C1",
 692		.irq_data = {
 693			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 694			.chip = "INT33FC:02",
 695			.index = 2,
 696			.trigger = ACPI_EDGE_SENSITIVE,
 697			.polarity = ACPI_ACTIVE_HIGH,
 698			.con_id = "bq24292i_irq",
 699		},
 700	}, {
 701		/* LP8557 Backlight controller */
 702		.board_info = {
 703			.type = "lp8557",
 704			.addr = 0x2c,
 705			.dev_name = "lp8557",
 706			.platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
 707		},
 708		.adapter_path = "\\_SB_.I2C3",
 709	}, {
 710		/* LC824206XA Micro USB Switch */
 711		.board_info = {
 712			.type = "lc824206xa",
 713			.addr = 0x48,
 714			.dev_name = "lc824206xa",
 715			.swnode = &lenovo_yoga_tab2_1380_lc824206xa_node,
 716		},
 717		.adapter_path = "\\_SB_.I2C3",
 718		.irq_data = {
 719			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 720			.chip = "INT33FC:02",
 721			.index = 1,
 722			.trigger = ACPI_LEVEL_SENSITIVE,
 723			.polarity = ACPI_ACTIVE_LOW,
 724			.con_id = "lc824206xa_irq",
 725		},
 726	}, {
 727		/* AL3320A ambient light sensor */
 728		.board_info = {
 729			.type = "al3320a",
 730			.addr = 0x1c,
 731			.dev_name = "al3320a",
 732		},
 733		.adapter_path = "\\_SB_.I2C5",
 734	}, {
 735		/* LSM303DA accelerometer + magnetometer */
 736		.board_info = {
 737			.type = "lsm303d",
 738			.addr = 0x1d,
 739			.dev_name = "lsm303d",
 740			.swnode = &lenovo_yoga_tab2_1380_lms303d_node,
 741		},
 742		.adapter_path = "\\_SB_.I2C5",
 743	}, {
 744		/* Synaptics RMI touchscreen */
 745		.board_info = {
 746			.type = "rmi4_i2c",
 747			.addr = 0x38,
 748			.dev_name = "rmi4_i2c",
 749			.platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
 750		},
 751		.adapter_path = "\\_SB_.I2C6",
 752		.irq_data = {
 753			.type = X86_ACPI_IRQ_TYPE_APIC,
 754			.index = 0x45,
 755			.trigger = ACPI_EDGE_SENSITIVE,
 756			.polarity = ACPI_ACTIVE_HIGH,
 757		},
 758	}
 759};
 760
 761static const struct property_entry lenovo_yoga_tab2_1380_fc_props[] __initconst = {
 762	PROPERTY_ENTRY_GPIO("uart3_txd-gpios", &baytrail_gpiochip_nodes[0], 57, GPIO_ACTIVE_HIGH),
 763	PROPERTY_ENTRY_GPIO("uart3_rxd-gpios", &baytrail_gpiochip_nodes[0], 61, GPIO_ACTIVE_HIGH),
 764	{ }
 765};
 766
 767static const struct platform_device_info lenovo_yoga_tab2_1380_pdevs[] __initconst = {
 768	{
 769		/* For the Tablet 2 Pro 1380's custom fast charging driver */
 770		.name = "lenovo-yoga-tab2-pro-1380-fastcharger",
 771		.id = PLATFORM_DEVID_NONE,
 772		.properties = lenovo_yoga_tab2_1380_fc_props,
 773	},
 774};
 775
 776static int __init lenovo_yoga_tab2_1380_init(struct device *dev)
 777{
 778	int ret;
 779
 780	/* To verify that the DMI matching works vs the 830 / 1050 models */
 781	pr_info("detected Lenovo Yoga Tablet 2 Pro 1380F/L\n");
 782
 783	ret = lenovo_yoga_tab2_830_1050_init_codec();
 784	if (ret)
 785		return ret;
 786
 787	/* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off() */
 788	lenovo_yoga_tab2_830_1050_sys_off_handler =
 789		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
 790					 lenovo_yoga_tab2_830_1050_power_off, NULL);
 791	if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
 792		return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
 793
 794	return 0;
 795}
 796
 797const struct x86_dev_info lenovo_yoga_tab2_1380_info __initconst = {
 798	.i2c_client_info = lenovo_yoga_tab2_1380_i2c_clients,
 799	.i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_i2c_clients),
 800	.pdev_info = lenovo_yoga_tab2_1380_pdevs,
 801	.pdev_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_pdevs),
 802	.gpio_button_swnodes = lenovo_yoga_tab2_830_1050_lid_swnodes,
 803	.swnode_group = lenovo_yoga_tab2_830_1050_swnodes,
 804	.modules = lenovo_yoga_tab2_modules,
 805	.gpiochip_type = X86_GPIOCHIP_BAYTRAIL,
 806	.init = lenovo_yoga_tab2_1380_init,
 807	.exit = lenovo_yoga_tab2_830_1050_exit,
 808};
 809
 810/* Lenovo Yoga Tab 3 Pro YT3-X90F */
 811
 812/*
 813 * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers,
 814 * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c.
 815 */
 816static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" };
 817static const char * const bq25890_1_psy[] = { "bq25890-charger-1" };
 818
 819static const struct property_entry fg_bq25890_1_supply_props[] = {
 820	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy),
 821	{ }
 822};
 823
 824static const struct software_node fg_bq25890_1_supply_node = {
 825	.properties = fg_bq25890_1_supply_props,
 826};
 827
 828/* bq25892 charger settings for the flat LiPo battery behind the screen */
 829static const struct property_entry lenovo_yt3_bq25892_0_props[] = {
 830	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers),
 831	PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40),
 832	PROPERTY_ENTRY_BOOL("linux,skip-reset"),
 833	/* Values taken from Android Factory Image */
 834	PROPERTY_ENTRY_U32("ti,charge-current", 2048000),
 835	PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
 836	PROPERTY_ENTRY_U32("ti,termination-current", 128000),
 837	PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
 838	PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000),
 839	PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
 840	PROPERTY_ENTRY_U32("ti,boost-max-current", 500000),
 841	PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
 842	{ }
 843};
 844
 845static const struct software_node lenovo_yt3_bq25892_0_node = {
 846	.properties = lenovo_yt3_bq25892_0_props,
 847};
 848
 849static const struct property_entry lenovo_yt3_hideep_ts_props[] = {
 850	PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
 851	PROPERTY_ENTRY_U32("touchscreen-size-y", 2560),
 852	PROPERTY_ENTRY_U32("touchscreen-max-pressure", 255),
 853	PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 7, GPIO_ACTIVE_LOW),
 854	{ }
 855};
 856
 857static const struct software_node lenovo_yt3_hideep_ts_node = {
 858	.properties = lenovo_yt3_hideep_ts_props,
 859};
 860
 861static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
 862	{
 863		/* bq27500 fuel-gauge for the flat LiPo battery behind the screen */
 864		.board_info = {
 865			.type = "bq27500",
 866			.addr = 0x55,
 867			.dev_name = "bq27500_0",
 868			.swnode = &fg_bq25890_supply_node,
 869		},
 870		.adapter_path = "\\_SB_.PCI0.I2C1",
 871	}, {
 872		/* bq25892 charger for the flat LiPo battery behind the screen */
 873		.board_info = {
 874			.type = "bq25892",
 875			.addr = 0x6b,
 876			.dev_name = "bq25892_0",
 877			.swnode = &lenovo_yt3_bq25892_0_node,
 878		},
 879		.adapter_path = "\\_SB_.PCI0.I2C1",
 880		.irq_data = {
 881			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 882			.chip = "INT33FF:01",
 883			.index = 5,
 884			.trigger = ACPI_EDGE_SENSITIVE,
 885			.polarity = ACPI_ACTIVE_LOW,
 886			.con_id = "bq25892_0_irq",
 887		},
 888	}, {
 889		/* bq27500 fuel-gauge for the round Li-ion cells in the hinge */
 890		.board_info = {
 891			.type = "bq27500",
 892			.addr = 0x55,
 893			.dev_name = "bq27500_1",
 894			.swnode = &fg_bq25890_1_supply_node,
 895		},
 896		.adapter_path = "\\_SB_.PCI0.I2C2",
 897	}, {
 898		/* HiDeep IST520E Touchscreen */
 899		.board_info = {
 900			.type = "hideep_ts",
 901			.addr = 0x6c,
 902			.dev_name = "hideep_ts",
 903			.swnode = &lenovo_yt3_hideep_ts_node,
 904		},
 905		.adapter_path = "\\_SB_.PCI0.I2C6",
 906		.irq_data = {
 907			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
 908			.chip = "INT33FF:03",
 909			.index = 77,
 910			.trigger = ACPI_LEVEL_SENSITIVE,
 911			.polarity = ACPI_ACTIVE_LOW,
 912			.con_id = "hideep_ts_irq",
 913		},
 914	}, {
 915		/* LP8557 Backlight controller */
 916		.board_info = {
 917			.type = "lp8557",
 918			.addr = 0x2c,
 919			.dev_name = "lp8557",
 920			.platform_data = &lenovo_lp8557_reg_only_pdata,
 921		},
 922		.adapter_path = "\\_SB_.PCI0.I2C1",
 923	}
 924};
 925
 926/*
 927 * The AOSP 3.5 mm Headset: Accessory Specification gives the following values:
 928 * Function A Play/Pause:           0 ohm
 929 * Function D Voice assistant:    135 ohm
 930 * Function B Volume Up           240 ohm
 931 * Function C Volume Down         470 ohm
 932 * Minimum Mic DC resistance     1000 ohm
 933 * Minimum Ear speaker impedance   16 ohm
 934 * Note the first max value below must be less then the min. speaker impedance,
 935 * to allow CTIA/OMTP detection to work. The other max values are the closest
 936 * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.
 937 */
 938static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
 939	{ .max =  11, .key = KEY_PLAYPAUSE },
 940	{ .max = 186, .key = KEY_VOICECOMMAND },
 941	{ .max = 348, .key = KEY_VOLUMEUP },
 942	{ .max = 752, .key = KEY_VOLUMEDOWN },
 943};
 944
 945/* YT3 WM5102 arizona_micd_config comes from Android kernel sources */
 946static struct arizona_micd_config lenovo_yt3_wm5102_micd_config[] = {
 947	{ 0, 1, 0 },
 948	{ ARIZONA_ACCDET_SRC, 2, 1 },
 949};
 950
 951static struct arizona_pdata lenovo_yt3_wm5102_pdata = {
 952	.irq_flags = IRQF_TRIGGER_LOW,
 953	.micd_detect_debounce = 200,
 954	.micd_ranges = arizona_micd_aosp_ranges,
 955	.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges),
 956	.hpdet_channel = ARIZONA_ACCDET_MODE_HPL,
 957
 958	/* Below settings come from Android kernel sources */
 959	.micd_bias_start_time = 1,
 960	.micd_rate = 6,
 961	.micd_configs = lenovo_yt3_wm5102_micd_config,
 962	.num_micd_configs = ARRAY_SIZE(lenovo_yt3_wm5102_micd_config),
 963	.micbias = {
 964		[0] = { /* MICBIAS1 */
 965			.mV = 2800,
 966			.ext_cap = 1,
 967			.discharge = 1,
 968			.soft_start = 0,
 969			.bypass = 0,
 970		},
 971		[1] = { /* MICBIAS2 */
 972			.mV = 2800,
 973			.ext_cap = 1,
 974			.discharge = 1,
 975			.soft_start = 0,
 976			.bypass = 0,
 977		},
 978		[2] = { /* MICBIAS2 */
 979			.mV = 2800,
 980			.ext_cap = 1,
 981			.discharge = 1,
 982			.soft_start = 0,
 983			.bypass = 0,
 984		},
 985	},
 986};
 987
 988static const struct property_entry lenovo_yt3_wm1502_props[] = {
 989	PROPERTY_ENTRY_GPIO("wlf,spkvdd-ena-gpios",
 990			    &cherryview_gpiochip_nodes[0], 75, GPIO_ACTIVE_HIGH),
 991	PROPERTY_ENTRY_GPIO("wlf,ldoena-gpios",
 992			    &cherryview_gpiochip_nodes[0], 81, GPIO_ACTIVE_HIGH),
 993	PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 82, GPIO_ACTIVE_HIGH),
 994	PROPERTY_ENTRY_GPIO("wlf,micd-pol-gpios", &arizona_gpiochip_node, 2, GPIO_ACTIVE_HIGH),
 995	{ }
 996};
 997
 998static const struct software_node lenovo_yt3_wm5102 = {
 999	.properties = lenovo_yt3_wm1502_props,
1000	.name = "wm5102",
1001};
1002
1003static const struct software_node *lenovo_yt3_swnodes[] = {
1004	&arizona_gpiochip_node,
1005	&lenovo_yt3_wm5102,
1006	NULL
1007};
1008
1009static const struct x86_spi_dev_info lenovo_yt3_spi_devs[] __initconst = {
1010	{
1011		/* WM5102 codec */
1012		.board_info = {
1013			.modalias = "wm5102",
1014			.platform_data = &lenovo_yt3_wm5102_pdata,
1015			.swnode = &lenovo_yt3_wm5102,
1016			.max_speed_hz = 5000000,
1017		},
1018		.ctrl_path = "\\_SB_.PCI0.SPI1",
1019		.irq_data = {
1020			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
1021			.chip = "INT33FF:00",
1022			.index = 91,
1023			.trigger = ACPI_LEVEL_SENSITIVE,
1024			.polarity = ACPI_ACTIVE_LOW,
1025			.con_id = "wm5102_irq",
1026		},
1027	}
1028};
1029
1030static int __init lenovo_yt3_init(struct device *dev)
1031{
1032	int ret;
1033
1034	/*
1035	 * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins
1036	 * connected to GPIOs, rather then having them hardwired to the correct
1037	 * values as is normally done.
1038	 *
1039	 * The bq25890_charger driver controls these through I2C, but this only
1040	 * works if not overridden by the pins. Set these pins here:
1041	 * 1. Set /CE to 1 to allow charging.
1042	 * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of
1043	 *    the main "bq25892_1" charger is used when necessary.
1044	 */
1045
1046	/* /CE pin */
1047	ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, "bq25892_0_ce",
1048					   true, GPIOD_OUT_HIGH, NULL);
1049	if (ret < 0)
1050		return ret;
1051
1052	/* OTG pin */
1053	ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, "bq25892_0_otg",
1054					   false, GPIOD_OUT_LOW, NULL);
1055	if (ret < 0)
1056		return ret;
1057
1058	/* Enable the regulators used by the touchscreen */
1059	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
1060	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
1061
1062	return 0;
1063}
1064
1065static const char * const lenovo_yt3_modules[] __initconst = {
1066	"spi_pxa2xx_platform",	/* For the SPI codec device */
1067	NULL
1068};
1069
1070const struct x86_dev_info lenovo_yt3_info __initconst = {
1071	.i2c_client_info = lenovo_yt3_i2c_clients,
1072	.i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients),
1073	.spi_dev_info = lenovo_yt3_spi_devs,
1074	.spi_dev_count = ARRAY_SIZE(lenovo_yt3_spi_devs),
1075	.swnode_group = lenovo_yt3_swnodes,
1076	.modules = lenovo_yt3_modules,
1077	.gpiochip_type = X86_GPIOCHIP_CHERRYVIEW,
1078	.init = lenovo_yt3_init,
1079};
~/ Read-only file preview.