blob: 7c48f3b16079b18f3611a22a5aa1eb5001b2b342 [file] [log] [blame]
// Copyright 2022 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEBUGD_SRC_HELPERS_TYPEC_CONNECTOR_CLASS_HELPER_UTILS_H_
#define DEBUGD_SRC_HELPERS_TYPEC_CONNECTOR_CLASS_HELPER_UTILS_H_
#include <iostream>
#include <string>
#include <vector>
#include <base/files/file_util.h>
namespace debugd {
namespace typec_connector_class_helper {
struct VdoField {
int index;
uint32_t mask;
std::string description;
};
enum ProductType {
kOther = 0,
kPD20PassiveCable = 1,
kPD20ActiveCable = 2,
kPD20AMA = 3,
kPD30PassiveCable = 4,
kPD30ActiveCable = 5,
kPD30AMA = 6,
kPD30VPD = 7,
kPD30UFP = 8,
kPD30DFP = 9,
kPD30DRD = 10,
kPD31PassiveCable = 11,
kPD31ActiveCable = 12,
kPD31VPD = 13,
kPD31UFP = 14,
kPD31DFP = 15,
kPD31DRD = 16,
};
enum PDRev {
kNone = 0,
kPD20 = 1,
kPD30 = 2,
kPD31 = 3,
};
constexpr char kTypecSysfs[] = "/sys/class/typec";
constexpr char kPortRegex[] = "port[0-9]+$";
constexpr char kPartnerAltModeRegex[] = "port[0-9]+-partner\\.[0-9]+$";
constexpr char kModeRegex[] = "mode[0-9]+$";
constexpr char kPlugRegex[] = "port[0-9]+\\-plug[0-9]+$";
constexpr char kPlugAltModeRegex[] = "port[0-9]+\\-plug[0-9]+\\.[0-9]+$";
// Masks for id_header fields.
constexpr uint32_t kPDUFPProductTypeMask = 0x38000000;
constexpr uint32_t kPDDFPProductTypeMask = 0x03800000;
// Expected id_header field results.
constexpr uint32_t kPD20PassiveCableComp = 0x20000000;
constexpr uint32_t kPD20ActiveCableComp = 0x18000000;
constexpr uint32_t kPD20AMAComp = 0x28000000;
constexpr uint32_t kPD30PassiveCableComp = 0x18000000;
constexpr uint32_t kPD30ActiveCableComp = 0x20000000;
constexpr uint32_t kPD30AMAComp = 0x28000000;
constexpr uint32_t kPD30VPDComp = 0x30000000;
constexpr uint32_t kPD30HubComp = 0x08000000;
constexpr uint32_t kPD30PeripheralComp = 0x10000000;
constexpr uint32_t kPD30DFPHubComp = 0x00800000;
constexpr uint32_t kPD30DFPHostComp = 0x01000000;
constexpr uint32_t kPD30PowerBrickComp = 0x01800000;
constexpr uint32_t kPD31PassiveCableComp = 0x18000000;
constexpr uint32_t kPD31ActiveCableComp = 0x20000000;
constexpr uint32_t kPD31VPDComp = 0x30000000;
constexpr uint32_t kPD31HubComp = 0x08000000;
constexpr uint32_t kPD31PeripheralComp = 0x10000000;
constexpr uint32_t kPD31DFPHubComp = 0x00800000;
constexpr uint32_t kPD31DFPHostComp = 0x01000000;
constexpr uint32_t kPD31PowerBrickComp = 0x01800000;
// VDO descriptions to obfuscate PID/VID with unknown PD revision.
const std::vector<VdoField> kOtherIDHeaderVDO = {{16, 0xffff0000, "Undefined"}};
const std::vector<VdoField> kOtherProductVDO = {{0, 0xffff, "Undefined"}};
// VDO descriptions from the USB PD Revision 2.0 and 3.1 specifications.
const std::vector<VdoField> kPD20CertStatVDO = {{0, 0xffffffff, "XID"}};
const std::vector<VdoField> kPD20ProductVDO = {{0, 0xffff, "bcdDevice"}};
const std::vector<VdoField> kPD20IDHeaderVDO = {
{16, 0x03ff0000, "Reserved"},
{26, 0x04000000, "Modal Operation Supported"},
{27, 0x38000000, "Product Type"},
{30, 0x40000000, "USB Capable as a USB Device"},
{31, 0x80000000, "USB Capable as a USB Host"},
};
const std::vector<VdoField> kPD20PassiveVDO = {
{0, 0x00000007, "USB Speed"},
{3, 0x00000008, "Reserved"},
{4, 0x00000010, "Vbus Through Cable"},
{5, 0x00000060, "Vbus Current Handling"},
{7, 0x00000080, "SSRX2 Directionality Support"},
{8, 0x00000100, "SSRX1 Directionality Support"},
{9, 0x00000200, "SSTX2 Directionality Support"},
{10, 0x00000400, "SSTX1 Directionality Support"},
{11, 0x00001800, "Cable Termination Type"},
{13, 0x0001e000, "Cable Latency"},
{17, 0x00020000, "Reserved"},
{18, 0x000c0000, "USB Type-C Plug to USB Type"},
{20, 0x00f00000, "Reserved"},
{24, 0x0f000000, "Firmware Version"},
{28, 0xf0000000, "HW Version"},
};
const std::vector<VdoField> kPD20ActiveVDO = {
{0, 0x00000007, "USB Speed"},
{3, 0x00000008, "SOP'' Controller Present"},
{4, 0x00000010, "Vbus Through Cable"},
{5, 0x00000060, "Vbus Current Handling"},
{7, 0x00000080, "SSRX2 Directionality Support"},
{8, 0x00000100, "SSRX1 Directionality Support"},
{9, 0x00000200, "SSTX2 Directionality Support"},
{10, 0x00000400, "SSTX1 Directionality Support"},
{11, 0x00001800, "Cable Termination Type"},
{13, 0x0001e000, "Cable Latency"},
{17, 0x00020000, "Reserved"},
{18, 0x000c0000, "USB Type-C Plug to USB Type"},
{20, 0x00f00000, "Reserved"},
{24, 0x0f000000, "Firmware Version"},
{28, 0xf0000000, "HW Version"},
};
const std::vector<VdoField> kPD20AMAVDO = {
{0, 0x00000007, "USB SS Signaling Support"},
{3, 0x00000008, "Vbus Required"},
{4, 0x00000010, "Vconn Required"},
{5, 0x000000e0, "Vconn Power"},
{8, 0x00000100, "SSRX2 Directionality Support"},
{9, 0x00000200, "SSRX1 Directionality Support"},
{10, 0x00000400, "SSTX2 Directionality Support"},
{11, 0x00000800, "SSTX1 Directionality Support"},
{12, 0x00fff000, "Reserved"},
{24, 0x0f000000, "Firmware Version"},
{28, 0xf0000000, "Hardware Version"},
};
const std::vector<VdoField> kPD30CertStatVDO = {{0, 0xffffffff, "XID"}};
const std::vector<VdoField> kPD30ProductVDO = {{0, 0xffff, "bcdDevice"}};
const std::vector<VdoField> kPD30IDHeaderVDO = {
{16, 0x007f0000, "Reserved"},
{23, 0x03800000, "Product Type (DFP)"},
{26, 0x04000000, "Modal Operation Supported"},
{27, 0x38000000, "Product Type (UFP/Cable Plug)"},
{30, 0x40000000, "USB Capable as a USB Device"},
{31, 0x80000000, "USB Capable as a USB Host"},
};
const std::vector<VdoField> kPD30PassiveVDO = {
{0, 0x00000007, "USB Speed"},
{3, 0x00000018, "Reserved"},
{5, 0x00000060, "Vbus Current Handling"},
{7, 0x00000180, "Reserved"},
{9, 0x00000600, "Maximum Vbus Voltage"},
{11, 0x00001800, "Cable Termination Type"},
{13, 0x0001e000, "Cable Latency"},
{17, 0x00020000, "Reserved"},
{18, 0x000c0000, "USB Type-C Plug to USB Type"},
{20, 0x00100000, "Reserved"},
{21, 0x00e00000, "VDO Version"},
{24, 0x0f000000, "Firmware Version"},
{28, 0xf0000000, "HW Version"},
};
const std::vector<VdoField> kPD30ActiveVDO1 = {
{0, 0x00000007, "USB Speed"},
{3, 0x00000008, "SOP'' Controller Present"},
{4, 0x00000010, "Vbus Through Cable"},
{5, 0x00000060, "Vbus Current Handling"},
{7, 0x00000080, "SBU Type"},
{8, 0x00000100, "SBU Supported"},
{9, 0x00000600, "Maximum Vbus Voltage"},
{11, 0x00001800, "Cable Termination Type"},
{13, 0x0001e000, "Cable Latency"},
{17, 0x00020000, "Reserved"},
{18, 0x000c0000, "Connector Type"},
{20, 0x00100000, "Reserved"},
{21, 0x00e00000, "VDO Version"},
{24, 0x0f000000, "Firmware Version"},
{28, 0xf0000000, "HW Version"},
};
const std::vector<VdoField> kPD30ActiveVDO2 = {
{0, 0x00000001, "USB Gen"},
{1, 0x00000002, "Reserved"},
{2, 0x00000004, "Optically Insulated Active Cable"},
{3, 0x00000008, "USB Lanes Supported"},
{4, 0x00000010, "USB 3.2 Supported"},
{5, 0x00000020, "USB 2.0 Supported"},
{6, 0x000000c00, "USB 2.0 Hub Hops Command"},
{8, 0x00000100, "USB4 Supported"},
{9, 0x00000200, "Active Element"},
{10, 0x00000400, "Physical Connection"},
{11, 0x00000800, "U3 to U0 Transition Mode"},
{12, 0x00007000, "U3/CLd Power"},
{15, 0x00008000, "Reserved"},
{16, 0x00ff0000, "Shutdown Tempurature"},
{24, 0xff000000, "Max Operating Tempurature"},
};
const std::vector<VdoField> kPD30AMAVDO = {
{0, 0x00000007, "USB Highest Speed"}, {3, 0x00000008, "Vbus Required"},
{4, 0x00000010, "Vconn Required"}, {5, 0x000000e0, "Vconn Power"},
{8, 0x001fff00, "Reserved"}, {21, 0x00e00000, "VDO Version"},
{24, 0x0f000000, "Firmware Version"}, {28, 0xf0000000, "Hardware Version"},
};
const std::vector<VdoField> kPD30VPDVDO = {
{0, 0x00000001, "Charge Through Support"},
{1, 0x0000007e, "Ground Impedance"},
{7, 0x00001f80, "Vbus Impedance"},
{13, 0x00002000, "Reserved"},
{14, 0x00004000, "Charge Through Current Support"},
{15, 0x00018000, "Maximum Vbus Voltage"},
{17, 0x001e0000, "Reserved"},
{21, 0x00e00000, "VDO Version"},
{24, 0x0f000000, "Firmware Version"},
{28, 0xf0000000, "HW Version"},
};
const std::vector<VdoField> kPD30UFPVDO1 = {
{0, 0x00000007, "USB Highest Speed"}, {3, 0x00000038, "Alternate Modes"},
{6, 0x00ffffc0, "Reserved"}, {24, 0x0f000000, "Device Capability"},
{28, 0x10000000, "Reserved"}, {29, 0xe0000000, "UFP VDO Version"},
};
const std::vector<VdoField> kPD30UFPVDO2 = {
{0, 0x0000007f, "USB3 Max Power"}, {7, 0x00003f80, "USB3 Min Power"},
{14, 0x0000c000, "Reserved"}, {16, 0x007f0000, "USB4 Max Power"},
{23, 0x3f800000, "USB4 Min Power"}, {30, 0xc0000000, "Reserved"},
};
const std::vector<VdoField> kPD30DFPVDO = {
{0, 0x0000001f, "Port Number"}, {5, 0x00ffffe0, "Reserved"},
{24, 0x07000000, "Host Capability"}, {27, 0x18000000, "Reserved"},
{29, 0xe0000000, "DFP VDO Version"},
};
const std::vector<VdoField> kPD31CertStatVDO = {{0, 0xffffffff, "XID"}};
const std::vector<VdoField> kPD31ProductVDO = {{0, 0xffff, "bcdDevice"}};
const std::vector<VdoField> kPD31IDHeaderVDO = {
{16, 0x001f0000, "Reserved"},
{21, 0x00600000, "Connector Type"},
{23, 0x03800000, "Product Type (DFP)"},
{26, 0x04000000, "Modal Operation Supported"},
{27, 0x38000000, "Product Type (UFP/Cable Plug)"},
{30, 0x40000000, "USB Capable as a USB Device"},
{31, 0x80000000, "USB Capable as a USB Host"},
};
const std::vector<VdoField> kPD31PassiveVDO = {
{0, 0x00000007, "USB Speed"},
{3, 0x00000018, "Reserved"},
{5, 0x00000060, "Vbus Current Handling"},
{7, 0x00000180, "Reserved"},
{9, 0x00000600, "Maximum Vbus Voltage"},
{11, 0x00001800, "Cable Termination Type"},
{13, 0x0001e000, "Cable Latency"},
{17, 0x00020000, "EPR Mode Cable"},
{18, 0x000c0000, "USB Type-C Plug to USB Type"},
{20, 0x00100000, "Reserved"},
{21, 0x00e00000, "VDO Version"},
{24, 0x0f000000, "Firmware Version"},
{28, 0xf0000000, "HW Version"},
};
const std::vector<VdoField> kPD31ActiveVDO1 = {
{0, 0x00000007, "USB Speed"},
{3, 0x00000008, "SOP'' Controller Present"},
{4, 0x00000010, "Vbus Through Cable"},
{5, 0x00000060, "Vbus Current Handling"},
{7, 0x00000080, "SBU Type"},
{8, 0x00000100, "SBU Supported"},
{9, 0x00000600, "Maximum Vbus Voltage"},
{11, 0x00001800, "Cable Termination Type"},
{13, 0x0001e000, "Cable Latency"},
{17, 0x00020000, "EPR Mode Cable"},
{18, 0x000c0000, "USB Type-C Plug to USB Type"},
{20, 0x00100000, "Reserved"},
{21, 0x00e00000, "VDO Version"},
{24, 0x0f000000, "Firmware Version"},
{28, 0xf0000000, "HW Version"},
};
const std::vector<VdoField> kPD31ActiveVDO2 = {
{0, 0x00000001, "USB Gen"},
{1, 0x00000002, "Reserved"},
{2, 0x00000004, "Optically Insulated Active Cable"},
{3, 0x00000008, "USB Lanes Supported"},
{4, 0x00000010, "USB 3.2 Supported"},
{5, 0x00000020, "USB 2.0 Supported"},
{6, 0x000000c00, "USB 2.0 Hub Hops Command"},
{8, 0x00000100, "USB4 Supported"},
{9, 0x00000200, "Active Element"},
{10, 0x00000400, "Physical Connection"},
{11, 0x00000800, "U3 to U0 Transition Mode"},
{12, 0x00007000, "U3/CLd Power"},
{15, 0x00008000, "Reserved"},
{16, 0x00ff0000, "Shutdown Tempurature"},
{24, 0xff000000, "Max Operating Tempurature"},
};
const std::vector<VdoField> kPD31VPDVDO = {
{0, 0x00000001, "Charge Through Support"},
{1, 0x0000007e, "Ground Impedance"},
{7, 0x00001f80, "Vbus Impedance"},
{13, 0x00002000, "Reserved"},
{14, 0x00004000, "Charge Through Current Support"},
{15, 0x00018000, "Maximum Vbus Voltage"},
{17, 0x001e0000, "Reserved"},
{21, 0x00e00000, "VDO Version"},
{24, 0x0f000000, "Firmware Version"},
{28, 0xf0000000, "HW Version"},
};
const std::vector<VdoField> kPD31UFPVDO = {
{0, 0x00000007, "USB Highest Speed"},
{3, 0x00000038, "Alternate Modes"},
{6, 0x00000040, "Vbus Required"},
{7, 0x00000080, "Vconn Required"},
{8, 0x00000700, "Vconn Power"},
{11, 0x003ff800, "Reserved"},
{22, 0x00c00000, "Connector Type (Legacy)"},
{24, 0x0f000000, "Device Capability"},
{28, 0x10000000, "Reserved"},
{29, 0xe0000000, "UFP VDO Version"},
};
const std::vector<VdoField> kPD31DFPVDO = {
{0, 0x0000001f, "Port Number"},
{5, 0x003fffe0, "Reserved"},
{22, 0x00c00000, "Connector Type (Legacy)"},
{24, 0x07000000, "Host Capability"},
{27, 0x18000000, "Reserved"},
{29, 0xe0000000, "DFP VDO Version"},
};
// GetIndentStr returns a string to be used as an indent based on the
// provided "indent" input.
std::string GetIndentStr(int indent);
// FormatString will remove trailing whitespace and add an indent to any new
// lines.
std::string FormatString(std::string file_str, int indent);
// ParseDirsAndExecute will look at subdirectories of a given directory and
// execute a passed function on directories matching a given regular expression.
void ParseDirsAndExecute(const base::FilePath& dir,
int indent,
char const* regex,
void (*func)(const base::FilePath&, int));
// PrintFile will print a file's contents in a "name: content" format and also
// add indentations to multiline strings.
void PrintFile(const base::FilePath& path, int indent);
// PrintDirFiles will print all files in a directory in a "name: content"
// format.
void PrintDirFiles(const base::FilePath& dir, int indent);
// GetPDRev will read the usb_power_delivery_revision file in a given directory
// and return a PDRev enum noting the supported PD Revision.
PDRev GetPDRev(const base::FilePath& dir);
// ReadVdo reads a file containing a 32 bit VDO value and loads it into a
// uint32_t pointer. It will return true if the file read is successful and
// false otherwise.
bool ReadVdo(const base::FilePath& path, uint32_t* vdo);
// PrintVdo reads a vdo value from a text file and converts it to a uint32_t
// variable then prints out the values of each field according to the
// vdo_description. If hide_data is set, the full vdo will not be printed to
// obfuscate user information.
void PrintVdo(const base::FilePath& vdo_file,
const std::vector<VdoField> vdo_description,
bool hide_data,
int indent);
// PrintAltMode will print the immediate files in an alternate mode directory,
// then print the files in a mode subdirectory.
void PrintAltMode(const base::FilePath& alt_mode, int indent);
// PrintPlugInfo will print the immediate files in an plug directory, then print
// the files in an alternate mode directory.
void PrintPlugInfo(const base::FilePath& plug, int indent);
// GetPartnerProductType will look at the id_header VDO and USB PD revision to
// decode what type of device is being parsed.
ProductType GetPartnerProductType(const base::FilePath& dir);
// Similar to GetPartnerProductType, GetCableProductType will use the USB PD
// revision and id_header VDO to determine which type of cable is being used.
ProductType GetCableProductType(const base::FilePath& dir);
// PrintPartnerIdentity prints the contents of an identity directory including
// VDO fields which are determined by product type.
void PrintPartnerIdentity(const base::FilePath& partner, int indent);
// Similar to PrintPartnerIdentity, PrintCableIdentity will display the contents
// of the identity directory for a cable including VDO fields.
void PrintCableIdentity(const base::FilePath& cable, int indent);
// PrintPartner will print the immediate information in the partner directory,
// then print the identity and alternate mode information.
void PrintPartner(const base::FilePath& port, int indent);
// PrintCable will print the immediate information in the cable directory,
// then print the identity and alternate mode information.
void PrintCable(const base::FilePath& port, int indent);
// PrintPortInfo will print relevant type-c connector class information for the
// port located at the sysfs path "port"
void PrintPortInfo(const base::FilePath& port, int indent);
} // namespace typec_connector_class_helper
} // namespace debugd
#endif // DEBUGD_SRC_HELPERS_TYPEC_CONNECTOR_CLASS_HELPER_UTILS_H_