usb2514: Support for board v3+

We use the new sysfs file to obtain the board version number and
configure the port swapping accordingly.  If the board_version sysfs
attribute is not present, we default to v2.

We also integrate resetting the hub chip from within this tool right
befeore writing the new register values via I2C.
This commit is contained in:
Harald Welte 2014-12-18 23:22:57 +01:00
parent 5c189003c5
commit eefee096cd
1 changed files with 80 additions and 1 deletions

View File

@ -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);