Linux Audio

Check our new training course

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