[RFC PATCH v2 3/3] platform/surface: Add Surface Go 2 board file

From: Daniel Scally
Date: Tue Aug 24 2021 - 19:06:52 EST


The DSDT tables on the Surface Go 2 contain no power control methods for
the world facing camera, so the regulator, gpio and clk frameworks have no
way to discover the appropriate connections and settings.

To compensate for the shortcomings, define the connections and other
parameters in a board file for this device.

Signed-off-by: Daniel Scally <djrscally@xxxxxxxxx>
---
Changes in v2:
- Re-written to use regulator_add_lookup() instead of the software
node api from v1.
- Added a dmi check to prevent the lookups from being added where the
platform running the code is not a Microsoft Surface Go 2 (Laurent)

MAINTAINERS | 6 ++
drivers/platform/surface/Kconfig | 10 +++
drivers/platform/surface/Makefile | 1 +
drivers/platform/surface/surface_go_2.c | 97 +++++++++++++++++++++++++
4 files changed, 114 insertions(+)
create mode 100644 drivers/platform/surface/surface_go_2.c

diff --git a/MAINTAINERS b/MAINTAINERS
index dc24e97d5386..891189cecd51 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12329,6 +12329,12 @@ F: Documentation/driver-api/surface_aggregator/clients/dtx.rst
F: drivers/platform/surface/surface_dtx.c
F: include/uapi/linux/surface_aggregator/dtx.h

+MICROSOFT SURFACE GO 2 SUPPORT
+M: Daniel Scally <djrscally@xxxxxxxxx>
+L: platform-driver-x86@xxxxxxxxxxxxxxx
+S: Maintained
+F: drivers/platform/surface/surface_go_2.c
+
MICROSOFT SURFACE GPE LID SUPPORT DRIVER
M: Maximilian Luz <luzmaximilian@xxxxxxxxx>
L: platform-driver-x86@xxxxxxxxxxxxxxx
diff --git a/drivers/platform/surface/Kconfig b/drivers/platform/surface/Kconfig
index 3105f651614f..0c55bd531592 100644
--- a/drivers/platform/surface/Kconfig
+++ b/drivers/platform/surface/Kconfig
@@ -124,6 +124,16 @@ config SURFACE_DTX
Aggregator Bus (i.e. CONFIG_SURFACE_AGGREGATOR_BUS=n). In that case,
some devices, specifically the Surface Book 3, will not be supported.

+config SURFACE_GO_2
+ bool "Surface Go 2 Specific Driver"
+ help
+ This board file performs some platform specific configuration to help
+ the regulator, gpio and clk frameworks link those resources to the
+ consuming devices - specifically the world facing camera.
+
+ Select Y here if your device is a Microsoft Surface Go 2, otherwise
+ select N.
+
config SURFACE_GPE
tristate "Surface GPE/Lid Support Driver"
depends on DMI
diff --git a/drivers/platform/surface/Makefile b/drivers/platform/surface/Makefile
index 32889482de55..9f858d2a3d77 100644
--- a/drivers/platform/surface/Makefile
+++ b/drivers/platform/surface/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SURFACE_AGGREGATOR) += aggregator/
obj-$(CONFIG_SURFACE_AGGREGATOR_CDEV) += surface_aggregator_cdev.o
obj-$(CONFIG_SURFACE_AGGREGATOR_REGISTRY) += surface_aggregator_registry.o
obj-$(CONFIG_SURFACE_DTX) += surface_dtx.o
+obj-$(CONFIG_SURFACE_GO_2) += surface_go_2.o
obj-$(CONFIG_SURFACE_GPE) += surface_gpe.o
obj-$(CONFIG_SURFACE_HOTPLUG) += surface_hotplug.o
obj-$(CONFIG_SURFACE_PLATFORM_PROFILE) += surface_platform_profile.o
diff --git a/drivers/platform/surface/surface_go_2.c b/drivers/platform/surface/surface_go_2.c
new file mode 100644
index 000000000000..31fd6a3ca4aa
--- /dev/null
+++ b/drivers/platform/surface/surface_go_2.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Author: Dan Scally <djrscally@xxxxxxxxx> */
+
+#include <linux/dmi.h>
+#include <linux/gpio/machine.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/regulator/machine.h>
+
+static const struct dmi_system_id surface_go_2_dmi_table[] = {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go 2"),
+ },
+ },
+ { }
+};
+
+static struct regulator_consumer_supply ana_consumer_supplies[] = {
+ REGULATOR_SUPPLY("avdd", "i2c-INT347A:00"),
+};
+
+static struct regulator_lookup ana_lookup = {
+ .device_name = "i2c-INT3472:05",
+ .regulator_name = "ANA",
+ .init_data = {
+ .constraints = {
+ .min_uV = 2815200,
+ .max_uV = 2815200,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ana_consumer_supplies),
+ .consumer_supplies = ana_consumer_supplies,
+ },
+};
+
+static struct regulator_consumer_supply vsio_consumer_supplies[] = {
+ REGULATOR_SUPPLY("dovdd", "i2c-INT347A:00"),
+};
+
+static struct regulator_lookup vsio_lookup = {
+ .device_name = "i2c-INT3472:05",
+ .regulator_name = "VSIO",
+ .init_data = {
+ .constraints = {
+ .min_uV = 1800600,
+ .max_uV = 1800600,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vsio_consumer_supplies),
+ .consumer_supplies = vsio_consumer_supplies,
+ },
+};
+
+static struct regulator_consumer_supply core_consumer_supplies[] = {
+ REGULATOR_SUPPLY("dvdd", "i2c-INT347A:00"),
+};
+
+static struct regulator_lookup core_lookup = {
+ .device_name = "i2c-INT3472:05",
+ .regulator_name = "CORE",
+ .init_data = {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(core_consumer_supplies),
+ .consumer_supplies = core_consumer_supplies,
+ },
+};
+
+static struct gpiod_lookup_table surface_go_2_gpios = {
+ .dev_id = "i2c-INT347A:00",
+ .table = {
+ GPIO_LOOKUP("tps68470-gpio", 9, "reset", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("tps68470-gpio", 7, "powerdown", GPIO_ACTIVE_LOW)
+ }
+};
+
+static int __init surface_go_2_init(void)
+{
+ if (!dmi_check_system(surface_go_2_dmi_table))
+ return -EINVAL;
+
+ regulator_add_lookup(&ana_lookup);
+ regulator_add_lookup(&vsio_lookup);
+ regulator_add_lookup(&core_lookup);
+ gpiod_add_lookup_table(&surface_go_2_gpios);
+
+ return 0;
+}
+device_initcall(surface_go_2_init);
--
2.25.1