brintos

brintos / linux-shallow public Read only

0
0
Text · 30.5 KiB · ae087f1 Raw
1049 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Board info for Lenovo X86 tablets which ship with Android as the factory image4 * and which have broken DSDT tables. The factory kernels shipped on these5 * devices typically have a bunch of things hardcoded, rather than specified6 * in their DSDT.7 *8 * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com>9 */10 11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt12 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 PWM32 * 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-standard34 * 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 the37 * 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 and40 * 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 backlight44 * 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 of47 * much less then 100%, severely limiting max brightness. In this case48 * the LP8557 should be configured to only take the I2C register into49 * account and the i915 driver must turn off the panel and the backlight50 * 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 protocol76 * reports ABS_MT_PRESSURE and ABS_MT_TOUCH_MAJOR which are not reported in HID77 * 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 of177 * 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	NULL231};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	NULL413};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 same434 * 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 for437 * 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 tablets526 * 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 EFI528 * 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/L571 *572 * The Lenovo Yoga Tablet 2 Pro 1380F/L mostly has the same design as the 830F/L573 * 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 604struct 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 729const char * const lenovo_yoga_tab2_1380_modules[] __initconst = {730	"bq24190_charger",            /* For the Vbus regulator for lc824206xa */731	NULL732};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	NULL768};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 ohm902 * Function D Voice assistant:    135 ohm903 * Function B Volume Up           240 ohm904 * Function C Volume Down         470 ohm905 * Minimum Mic DC resistance     1000 ohm906 * Minimum Ear speaker impedance   16 ohm907 * 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 closest909 * 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 pins987	 * connected to GPIOs, rather then having them hardwired to the correct988	 * values as is normally done.989	 *990	 * The bq25890_charger driver controls these through I2C, but this only991	 * 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 of994	 *    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	NULL1039};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};1049