#include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
+#include <linux/platform_data/lp855x.h>
 #include <linux/platform_device.h>
 #include <linux/power/bq24190_charger.h>
+#include <linux/rmi.h>
 #include <linux/serdev.h>
 #include <linux/string.h>
 /* For gpio_get_desc() which is EXPORT_SYMBOL_GPL() */
 static const char * const bq24190_psy[] = { "bq24190-charger" };
 static const char * const bq25890_psy[] = { "bq25890-charger" };
 
+static const struct property_entry fg_bq24190_supply_props[] = {
+       PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
+       { }
+};
+
+static const struct software_node fg_bq24190_supply_node = {
+       .properties = fg_bq24190_supply_props,
+};
+
 static const struct property_entry fg_bq25890_supply_props[] = {
        PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_psy),
        { }
        .i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x9x_i2c_clients),
 };
 
+/* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */
+static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
+       PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
+       PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
+       PROPERTY_ENTRY_BOOL("omit-battery-class"),
+       PROPERTY_ENTRY_BOOL("disable-reset"),
+       { }
+};
+
+static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
+       .properties = lenovo_yoga_tab2_830_1050_bq24190_props,
+};
+
+/* This gets filled by lenovo_yoga_tab2_830_1050_init() */
+static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
+
+static struct lp855x_platform_data lenovo_yoga_tab2_830_1050_lp8557_pdata = {
+       .device_control = 0x86,
+       .initial_brightness = 128,
+};
+
+static const struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initconst = {
+       {
+               /* bq24292i battery charger */
+               .board_info = {
+                       .type = "bq24190",
+                       .addr = 0x6b,
+                       .dev_name = "bq24292i",
+                       .swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
+                       .platform_data = &bq24190_pdata,
+               },
+               .adapter_path = "\\_SB_.I2C1",
+               .irq_data = {
+                       .type = X86_ACPI_IRQ_TYPE_GPIOINT,
+                       .chip = "INT33FC:02",
+                       .index = 2,
+                       .trigger = ACPI_EDGE_SENSITIVE,
+                       .polarity = ACPI_ACTIVE_HIGH,
+               },
+       }, {
+               /* BQ27541 fuel-gauge */
+               .board_info = {
+                       .type = "bq27541",
+                       .addr = 0x55,
+                       .dev_name = "bq27541",
+                       .swnode = &fg_bq24190_supply_node,
+               },
+               .adapter_path = "\\_SB_.I2C1",
+       }, {
+               /* Synaptics RMI touchscreen */
+               .board_info = {
+                       .type = "rmi4_i2c",
+                       .addr = 0x38,
+                       .dev_name = "rmi4_i2c",
+                       .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
+               },
+               .adapter_path = "\\_SB_.I2C6",
+               .irq_data = {
+                       .type = X86_ACPI_IRQ_TYPE_APIC,
+                       .index = 0x45,
+                       .trigger = ACPI_EDGE_SENSITIVE,
+                       .polarity = ACPI_ACTIVE_HIGH,
+               },
+       }, {
+               /* LP8557 Backlight controller */
+               .board_info = {
+                       .type = "lp8557",
+                       .addr = 0x2c,
+                       .dev_name = "lp8557",
+                       .platform_data = &lenovo_yoga_tab2_830_1050_lp8557_pdata,
+               },
+               .adapter_path = "\\_SB_.I2C3",
+       },
+};
+
+static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
+       .dev_id = "intel-int3496",
+       .table = {
+               GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
+               { }
+       },
+};
+
+static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = {
+       &lenovo_yoga_tab2_830_1050_int3496_gpios,
+       NULL
+};
+
+static int __init lenovo_yoga_tab2_830_1050_init(void);
+static void lenovo_yoga_tab2_830_1050_exit(void);
+
+static struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initdata = {
+       .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
+       /* i2c_client_count gets set by lenovo_yoga_tab2_830_1050_init() */
+       .pdev_info = int3496_pdevs,
+       .pdev_count = ARRAY_SIZE(int3496_pdevs),
+       .gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios,
+       .bat_swnode = &generic_lipo_hv_4v35_battery_node,
+       .modules = bq24190_modules,
+       .invalid_aei_gpiochip = "INT33FC:02",
+       .init = lenovo_yoga_tab2_830_1050_init,
+};
+
+/*
+ * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
+ * mainboard, but they need some different treatment related to the display:
+ * 1. The 830 uses a portrait LCD panel with a landscape touchscreen, requiring
+ *    the touchscreen driver to adjust the touch-coords to match the LCD.
+ * 2. Both use an TI LP8557 LED backlight controller. On the 1050 the LP8557's
+ *    PWM input is connected to the PMIC's PWM output and everything works fine
+ *    with the defaults programmed into the LP8557 by the BIOS.
+ *    But on the 830 the LP8557's PWM input is connected to a PWM output coming
+ *    from the LCD panel's controller. The Android code has a hack in the i915
+ *    driver to write the non-standard DSI reg 0x9f with the desired backlight
+ *    level to set the duty-cycle of the LCD's PWM output.
+ *
+ *    To avoid having to have a similar hack in the mainline kernel the LP8557
+ *    entry in lenovo_yoga_tab2_830_1050_i2c_clients instead just programs the
+ *    LP8557 to directly set the level, ignoring the PWM input. This means that
+ *    the LP8557 i2c_client should only be instantiated on the 830.
+ */
+static int __init lenovo_yoga_tab2_830_1050_init_display(void)
+{
+       struct gpio_desc *gpiod;
+       int ret;
+
+       /* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
+       ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, &gpiod);
+       if (ret)
+               return ret;
+
+       ret = gpiod_get_value_cansleep(gpiod);
+       if (ret) {
+               pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
+               lenovo_yoga_tab2_830_1050_info.i2c_client_count =
+                       ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients) - 1;
+       } else {
+               pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
+               lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
+               lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
+               lenovo_yoga_tab2_830_1050_info.i2c_client_count =
+                       ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients);
+       }
+
+       return 0;
+}
+
+static int __init lenovo_yoga_tab2_830_1050_init(void)
+{
+       int ret;
+
+       ret = lenovo_yoga_tab2_830_1050_init_display();
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 /* Nextbook Ares 8 tablets have an Android factory img with everything hardcoded */
 static const char * const nextbook_ares8_accel_mount_matrix[] = {
        "0", "-1", "0",
                },
                .driver_data = (void *)&lenovo_yogabook_x9x_info,
        },
+       {
+               /*
+                * Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10"
+                * Lenovo Yoga Tablet 2 use the same mainboard)
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
+                       DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
+                       /* Partial match on beginning of BIOS version */
+                       DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
+               },
+               .driver_data = (void *)&lenovo_yoga_tab2_830_1050_info,
+       },
        {
                /* Nextbook Ares 8 */
                .matches = {