diff --git a/recipes-bsp/sob-odu/files/usb2514.c b/recipes-bsp/sob-odu/files/usb2514.c index acc7540..2669a20 100644 --- a/recipes-bsp/sob-odu/files/usb2514.c +++ b/recipes-bsp/sob-odu/files/usb2514.c @@ -33,6 +33,10 @@ #define USB2514_SLAVE_ADDR 0x2C +#define BOARD_VER_PATH "/sys/devices/platform/sob-odu.0/board_version" +#define RESET_PATH "/sys/devices/platform/sob-odu.0/gpio_hub_reset/value" +#define RESET_PATH_OLD "/sys/class/gpio/gpio62/value" + /* Default configuration as per data sheet */ static const uint8_t usb2514_default[256] = { 0x24, 0x04, 0x14, 0x25, 0xB3, 0x0B, 0x9B, 0x20, /* 0x00 */ @@ -70,7 +74,7 @@ static const uint8_t usb2514_default[256] = { }; /* Default configuration as per data sheet */ -static const uint8_t usb2514_odu[256] = { +static uint8_t usb2514_odu[256] = { 0x24, 0x04, 0x14, 0x25, 0xB3, 0x0B, 0x9B, 0x20, /* 0x00 */ 0x02, 0x00, 0x00, 0x00, 0x01, 0x32, 0x01, 0x32, /* 0x08 */ 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10 */ @@ -140,9 +144,61 @@ static int write_regs(const uint8_t *regs) return rc; } +/* attempt to obtain the board version from sysfs */ +static int get_board_version(void) +{ + FILE *f; + unsigned int ver; + + f = fopen(BOARD_VER_PATH, "r"); + if (!f) + return -1; + + if (fscanf(f, "%u", &ver) != 1) { + fclose(f); + return -2; + } + + fclose(f); + + return ver; +} + +/* attempt to reset the hub via sysfs */ +static int reset_hub(void) +{ + FILE *f; + int invert_logic = 0; + + f = fopen(RESET_PATH, "w"); + if (!f) { + f = fopen(RESET_PATH_OLD, "w"); + if (!f) + return -1; + invert_logic = 1; + } + + if (invert_logic) + fputs("0", f); + else + fputs("1", f); + + usleep(10000); + rewind(f); + + if (invert_logic) + fputs("1", f); + else + fputs("0", f); + + fclose(f); + return 0; +} + int main(int argc, char **argv) { int rc; + int board_version; int adapter_nr; long slave_addr = USB2514_SLAVE_ADDR; char filename[PATH_MAX]; @@ -164,12 +220,35 @@ int main(int argc, char **argv) get_support(); + board_version = get_board_version(); + if (board_version >= 3) { + /* on board version 3 and later we don't need to swap + * USB downlink port 1 */ + printf("Detected board >= v3, not swapping DN1\n"); + usb2514_odu[0xFA] = 0x0C; + } else if (board_version == 1) { + /* ports are still swapped in hardware */ + printf("Detected board v1, not swapping any ports\n"); + usb2514_odu[0xFA] = 0x00; + } else if (board_version == 2) { + printf("Detected board v2, swapping DN1, DN2 and DN3\n"); + /* default */ + } else { + printf("Assuming board v2, swapping DN1, DN2 and DN3\n"); + /* default */ + } + rc = ioctl(g_fd, I2C_SLAVE, slave_addr); if (rc < 0) { fprintf(stderr, "Error setting slave addr: %d\n", rc); exit(1); } + /* First reset the USB hub before loading data into it */ + if (reset_hub() < 0) { + fprintf(stderr, "Couldn't reset the USB hub!\n"); + } + rc = write_regs(usb2514_odu); if (rc < 0) { fprintf(stderr, "Error writing default regs: %d\n", rc);