// SPDX-License-Identifier: GPL-2.0-or-later /* * Driver to power on the Analogix ANX7428 USB Type-C crosspoint switch * on MeeGoPad top-set boxes. * * The MeeGoPad T8 and T9 are Cherry Trail top-set boxes which * use an ANX7428 to provide a Type-C port with USB3.1 Gen 1 and * DisplayPort over Type-C alternate mode support. * * The ANX7428 has a microcontroller which takes care of the PD * negotiation and automatically sets the builtin Crosspoint Switch * to send the right signal to the 4 highspeed pairs of the Type-C * connector. It also takes care of HPD and AUX channel routing for * DP alternate mode. * * IOW the ANX7428 operates fully autonomous and to the x5-Z8350 SoC * things look like there simply is a USB-3 Type-A connector and a * separate DisplayPort connector. Except that the BIOS does not * power on the ANX7428 at boot. This driver takes care of powering * on the ANX7428. * * It should be possible to tell the micro-controller which data- and/or * power-role to negotiate and to swap the role(s) after negotiation * but the MeeGoPad top-set boxes always draw their power from a separate * power-connector and they only support USB host-mode. So this functionality * is unnecessary and due to lack of documentation this is tricky to support. * * For a more complete ANX7428 driver see drivers/usb/misc/anx7418/ of * the LineageOS kernel for the LG G5 (International) aka the LG H850: * https://github.com/LineageOS/android_kernel_lge_msm8996/ * * (C) Copyright 2024 Hans de Goede <[email protected]> */ #include <linux/acpi.h> #include <linux/bits.h> #include <linux/delay.h> #include <linux/dev_printk.h> #include <linux/dmi.h> #include <linux/err.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/iopoll.h> #include <linux/module.h> #include <linux/types.h> /* Register addresses and fields */ #define VENDOR_ID … #define DEVICE_ID … #define TX_STATUS … #define STATUS_SUCCESS … #define STATUS_ERROR … #define OCM_STARTUP … static bool force; module_param(force, bool, 0444); MODULE_PARM_DESC(…) …; static const struct acpi_gpio_params enable_gpio = …; static const struct acpi_gpio_params reset_gpio = …; static const struct acpi_gpio_mapping meegopad_anx7428_gpios[] = …; static const struct dmi_system_id meegopad_anx7428_ids[] = …; static int anx7428_probe(struct i2c_client *client) { … } static const struct acpi_device_id anx7428_acpi_match[] = …; MODULE_DEVICE_TABLE(acpi, anx7428_acpi_match); static struct i2c_driver anx7428_driver = …; module_i2c_driver(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;