ppps: add support for separate USB-3 PPPS path

Some devices / hubs require switching both USB-2 and USB-3 ports to
function correctly. Add ppps3_path device option to control USB-3 port
in addition to the USB-2 port.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
This commit is contained in:
Dmitry Baryshkov
2023-10-10 16:09:20 +03:00
parent df832c0023
commit bb653da577
3 changed files with 33 additions and 14 deletions

View File

@@ -36,6 +36,7 @@ struct device {
char *serial;
char *description;
char *ppps_path;
char *ppps3_path;
struct list_head *users;
unsigned voltage;
bool tickle_mmc;

View File

@@ -189,6 +189,8 @@ static void parse_board(struct device_parser *dp)
dev->usb_always_on = !strcmp(value, "true");
} else if (!strcmp(key, "ppps_path")) {
dev->ppps_path = strdup(value);
} else if (!strcmp(key, "ppps3_path")) {
dev->ppps3_path = strdup(value);
} else {
fprintf(stderr, "device parser: unknown key \"%s\"\n", key);
exit(1);

44
ppps.c
View File

@@ -45,25 +45,17 @@
#include "device.h"
#define PPPS_BASE_PATH "/sys/bus/usb/devices"
#define PPPS_BASE_PATH_LEN strlen(PPPS_BASE_PATH)
#define PPPS_BASE_PATH "/sys/bus/usb/devices/%s/disable"
void ppps_power(struct device *dev, bool on)
void ppps_power_path(const char *ppps_path, bool on)
{
static char *path = NULL;
int rc, fd;
/* Only need to figure out the whole string once */
if (!path) {
/* ppps_path should be like "2-2:1.0/2-2-port2" */
asprintf(&path, "%s/%s/disable", PPPS_BASE_PATH, dev->ppps_path);
}
//fprintf(stderr, "ppps_power: %-3s %s\n", on ? "on" : "off", path);
// fprintf(stderr, "ppps_power: %-3s %s\n", on ? "on" : "off", path);
fd = open(path, O_WRONLY);
fd = open(ppps_path, O_WRONLY);
if (fd < 0) {
fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno));
fprintf(stderr, "failed to open %s: %s\n", ppps_path, strerror(errno));
if (errno != ENOENT)
fprintf(stderr, "Maybe missing permissions (see https://git.io/JIB2Z)\n");
return;
@@ -71,7 +63,31 @@ void ppps_power(struct device *dev, bool on)
rc = write(fd, on ? "0" : "1", 1);
if (rc < 0)
fprintf(stderr, "failed to write to %s: %s\n", path, strerror(errno));
fprintf(stderr, "failed to write to %s: %s\n", ppps_path, strerror(errno));
close(fd);
}
void ppps_power(struct device *dev, bool on)
{
/* ppps_path should be like "2-2:1.0/2-2-port2" */
if (dev->ppps_path[0] != '/') {
char *temp;
asprintf(&temp, PPPS_BASE_PATH, dev->ppps_path);
free(dev->ppps_path);
dev->ppps_path = temp;
}
if (dev->ppps3_path[0] != '/') {
char *temp;
asprintf(&temp, PPPS_BASE_PATH, dev->ppps3_path);
free(dev->ppps3_path);
dev->ppps3_path = temp;
}
ppps_power_path(dev->ppps_path, on);
if (dev->ppps3_path)
ppps_power_path(dev->ppps3_path, on);
}