diff mbox series

[v2,3/3] platform/x86: x86-android-tablets: Add support for Vexia EDU ATLA 10 tablet

Message ID 20241104200848.58693-4-hdegoede@redhat.com (mailing list archive)
State Accepted, archived
Headers show
Series platform/x86: x86-android-tablets: Add support for Vexia EDU ATLA 10 tablet | expand

Commit Message

Hans de Goede Nov. 4, 2024, 8:08 p.m. UTC
Add support for the Vexia EDU ATLA 10 tablet, Android 4.2/4.4 + Guadalinex
Ubuntu tablet distributed to schools in the Spanish Andalucía region.

Besides the usual broken DSDT issues this tablet is special because all
its LPSS island peripherals are enumerated as PCI devices rather then as
ACPI devices as they typically are.

At the same time there are disabled (_STA=0) ACPI devices for
the peripherals and child ACPI devices for e.g. attached I2C/SDIO devices
are children of these disabled ACPI devices and thus will not be used
by Linux since the parent is disabled.

So besides the usual manual i2c-client instantiation for accel/touchscreen
this tablet also requires manual i2c-client instantiation for the codec
and for the PMIC.

Also it seems the mainboard was designed for Windows not Android, so
it has an I2C attached embedded controller instead of allowing direct
access to the charger + fuel-gauge chips as is usual with Android boards.

Normally when there is an embedded controller, there also is ACPI battery
support, but since this shipped with Android that is missing and Linux
needs to have a power_supply class driver talking directly to the EC.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
- Use pci_get_domain_bus_and_slot()
- Move "depends on PCI" to patch adding get_i2c_adap_by_pci_parent() helper
---
 .../platform/x86/x86-android-tablets/dmi.c    |  10 ++
 .../platform/x86/x86-android-tablets/other.c  | 163 ++++++++++++++++++
 .../x86-android-tablets/x86-android-tablets.h |   1 +
 3 files changed, 174 insertions(+)

Comments

Andy Shevchenko Nov. 5, 2024, 8:28 a.m. UTC | #1
On Mon, Nov 4, 2024 at 10:09 PM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Add support for the Vexia EDU ATLA 10 tablet, Android 4.2/4.4 + Guadalinex
> Ubuntu tablet distributed to schools in the Spanish Andalucía region.
>
> Besides the usual broken DSDT issues this tablet is special because all
> its LPSS island peripherals are enumerated as PCI devices rather then as
> ACPI devices as they typically are.
>
> At the same time there are disabled (_STA=0) ACPI devices for
> the peripherals and child ACPI devices for e.g. attached I2C/SDIO devices
> are children of these disabled ACPI devices and thus will not be used
> by Linux since the parent is disabled.
>
> So besides the usual manual i2c-client instantiation for accel/touchscreen
> this tablet also requires manual i2c-client instantiation for the codec
> and for the PMIC.
>
> Also it seems the mainboard was designed for Windows not Android, so
> it has an I2C attached embedded controller instead of allowing direct
> access to the charger + fuel-gauge chips as is usual with Android boards.
>
> Normally when there is an embedded controller, there also is ACPI battery
> support, but since this shipped with Android that is missing and Linux
> needs to have a power_supply class driver talking directly to the EC.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

...

> +               .adapter_path = "0000:00:18.1",

> +               .adapter_path = "0000:00:18.2",

> +               .adapter_path = "0000:00:18.5",

> +               .adapter_path = "0000:00:18.6",

> +               .adapter_path = "0000:00:18.7",

...

> +       .use_pci_devname = true,

Just realized that you may do something like this to the above and
also use pci_get_...() instead of iterating over the I2C type of
devices. But you can do it later.
diff mbox series

Patch

diff --git a/drivers/platform/x86/x86-android-tablets/dmi.c b/drivers/platform/x86/x86-android-tablets/dmi.c
index 17f6da96aa01..3e5fa3b6e2fd 100644
--- a/drivers/platform/x86/x86-android-tablets/dmi.c
+++ b/drivers/platform/x86/x86-android-tablets/dmi.c
@@ -179,6 +179,16 @@  const struct dmi_system_id x86_android_tablet_ids[] __initconst = {
 		},
 		.driver_data = (void *)&peaq_c1010_info,
 	},
+	{
+		/* Vexia Edu Atla 10 tablet 9V version */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
+			/* Above strings are too generic, also match on BIOS date */
+			DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
+		},
+		.driver_data = (void *)&vexia_edu_atla10_info,
+	},
 	{
 		/* Whitelabel (sold as various brands) TM800A550L */
 		.matches = {
diff --git a/drivers/platform/x86/x86-android-tablets/other.c b/drivers/platform/x86/x86-android-tablets/other.c
index 7db8aa58b907..3ed808ac5b6b 100644
--- a/drivers/platform/x86/x86-android-tablets/other.c
+++ b/drivers/platform/x86/x86-android-tablets/other.c
@@ -12,6 +12,7 @@ 
 #include <linux/gpio/machine.h>
 #include <linux/input.h>
 #include <linux/leds.h>
+#include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
 
@@ -597,6 +598,168 @@  const struct x86_dev_info whitelabel_tm800a550l_info __initconst = {
 	.gpiod_lookup_tables = whitelabel_tm800a550l_gpios,
 };
 
+/*
+ * Vexia EDU ATLA 10 tablet, Android 4.2 / 4.4 + Guadalinex Ubuntu tablet
+ * distributed to schools in the Spanish Andalucía region.
+ */
+const char * const crystal_cove_pwrsrc_psy[] = { "crystal_cove_pwrsrc" };
+
+static const struct property_entry vexia_edu_atla10_ulpmc_props[] = {
+	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", crystal_cove_pwrsrc_psy),
+	{ }
+};
+
+const struct software_node vexia_edu_atla10_ulpmc_node = {
+	.properties = vexia_edu_atla10_ulpmc_props,
+};
+
+static const char * const vexia_edu_atla10_accel_mount_matrix[] = {
+	"0", "-1", "0",
+	"1", "0", "0",
+	"0", "0", "1"
+};
+
+static const struct property_entry vexia_edu_atla10_accel_props[] = {
+	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", vexia_edu_atla10_accel_mount_matrix),
+	{ }
+};
+
+static const struct software_node vexia_edu_atla10_accel_node = {
+	.properties = vexia_edu_atla10_accel_props,
+};
+
+static const struct property_entry vexia_edu_atla10_touchscreen_props[] = {
+	PROPERTY_ENTRY_U32("hid-descr-addr", 0x0000),
+	PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
+	{ }
+};
+
+static const struct software_node vexia_edu_atla10_touchscreen_node = {
+	.properties = vexia_edu_atla10_touchscreen_props,
+};
+
+static const struct property_entry vexia_edu_atla10_pmic_props[] = {
+	PROPERTY_ENTRY_BOOL("linux,register-pwrsrc-power_supply"),
+	{ }
+};
+
+static const struct software_node vexia_edu_atla10_pmic_node = {
+	.properties = vexia_edu_atla10_pmic_props,
+};
+
+static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initconst = {
+	{	/* I2C attached embedded controller, used to access fuel-gauge */
+		.board_info = {
+			.type = "vexia_atla10_ec",
+			.addr = 0x76,
+			.dev_name = "ulpmc",
+			.swnode = &vexia_edu_atla10_ulpmc_node,
+		},
+		.adapter_path = "0000:00:18.1",
+	},
+	{	/* RT5642 audio codec */
+		.board_info = {
+			.type = "rt5640",
+			.addr = 0x1c,
+			.dev_name = "rt5640",
+		},
+		.adapter_path = "0000:00:18.2",
+		.irq_data = {
+			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
+			.chip = "INT33FC:02",
+			.index = 4,
+			.trigger = ACPI_EDGE_SENSITIVE,
+			.polarity = ACPI_ACTIVE_HIGH,
+			.con_id = "rt5640_irq",
+		},
+	},
+	{
+		/* kxtj21009 accelerometer */
+		.board_info = {
+			.type = "kxtj21009",
+			.addr = 0x0f,
+			.dev_name = "kxtj21009",
+			.swnode = &vexia_edu_atla10_accel_node,
+		},
+		.adapter_path = "0000:00:18.5",
+	}, {
+		/* FT5416DQ9 touchscreen controller */
+		.board_info = {
+			.type = "hid-over-i2c",
+			.addr = 0x38,
+			.dev_name = "FTSC1000",
+			.swnode = &vexia_edu_atla10_touchscreen_node,
+		},
+		.adapter_path = "0000:00:18.6",
+		.irq_data = {
+			.type = X86_ACPI_IRQ_TYPE_APIC,
+			.index = 0x45,
+			.trigger = ACPI_LEVEL_SENSITIVE,
+			.polarity = ACPI_ACTIVE_HIGH,
+		},
+	}, {
+		/* Crystal Cove PMIC */
+		.board_info = {
+			.type = "intel_soc_pmic_crc",
+			.addr = 0x6e,
+			.dev_name = "intel_soc_pmic_crc",
+			.swnode = &vexia_edu_atla10_pmic_node,
+		},
+		.adapter_path = "0000:00:18.7",
+		.irq_data = {
+			.type = X86_ACPI_IRQ_TYPE_APIC,
+			.index = 0x43,
+			.trigger = ACPI_LEVEL_SENSITIVE,
+			.polarity = ACPI_ACTIVE_HIGH,
+		},
+	}
+};
+
+static struct gpiod_lookup_table vexia_edu_atla10_ft5416_gpios = {
+	.dev_id = "i2c-FTSC1000",
+	.table = {
+		GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_LOW),
+		{ }
+	},
+};
+
+static struct gpiod_lookup_table * const vexia_edu_atla10_gpios[] = {
+	&vexia_edu_atla10_ft5416_gpios,
+	NULL
+};
+
+static int __init vexia_edu_atla10_init(struct device *dev)
+{
+	struct pci_dev *pdev;
+	int ret;
+
+	/* Enable the Wifi module by setting the wifi_enable pin to 1 */
+	ret = x86_android_tablet_get_gpiod("INT33FC:02", 20, "wifi_enable",
+					   false, GPIOD_OUT_HIGH, NULL);
+	if (ret)
+		return ret;
+
+	/* Reprobe the SDIO controller to enumerate the now enabled Wifi module */
+	pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0x11, 0));
+	if (!pdev)
+		return -EPROBE_DEFER;
+
+	ret = device_reprobe(&pdev->dev);
+	if (ret)
+		pci_warn(pdev, "Reprobing error: %d\n", ret);
+
+	pci_dev_put(pdev);
+	return 0;
+}
+
+const struct x86_dev_info vexia_edu_atla10_info __initconst = {
+	.i2c_client_info = vexia_edu_atla10_i2c_clients,
+	.i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_i2c_clients),
+	.gpiod_lookup_tables = vexia_edu_atla10_gpios,
+	.init = vexia_edu_atla10_init,
+	.use_pci_devname = true,
+};
+
 /*
  * The firmware node for ktd2026 on Xaomi pad2. It composed of a RGB LED node
  * with three subnodes for each color (B/G/R). The RGB LED node is named
diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h
index d26a4792eb0e..0fc7e8cff672 100644
--- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h
+++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h
@@ -120,6 +120,7 @@  extern const struct x86_dev_info nextbook_ares8_info;
 extern const struct x86_dev_info nextbook_ares8a_info;
 extern const struct x86_dev_info peaq_c1010_info;
 extern const struct x86_dev_info whitelabel_tm800a550l_info;
+extern const struct x86_dev_info vexia_edu_atla10_info;
 extern const struct x86_dev_info xiaomi_mipad2_info;
 extern const struct dmi_system_id x86_android_tablet_ids[];