diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-10-09 12:12:13 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-10-09 12:12:13 +0000 |
commit | a3f3953ab2f245cd47aab3563014c04f1a70f9be (patch) | |
tree | d41fef4bdbf207b7c5cf9d8b9568b85cf5a4ea30 /sys/src | |
parent | 610071bb8b28fe8a871b97f0332e47c3d921f3cf (diff) |
usbsdmux: Add program to control usb-sd-mux device
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/cmd/aux/mkfile | 1 | ||||
-rw-r--r-- | sys/src/cmd/aux/usbsdmux.c | 112 |
2 files changed, 113 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/mkfile b/sys/src/cmd/aux/mkfile index 1ef302c45..e3024b5ba 100644 --- a/sys/src/cmd/aux/mkfile +++ b/sys/src/cmd/aux/mkfile @@ -46,6 +46,7 @@ TARG=\ txt2uimage\ unbflz\ usage\ + usbsdmux\ write\ wacom\ wikifmt\ diff --git a/sys/src/cmd/aux/usbsdmux.c b/sys/src/cmd/aux/usbsdmux.c new file mode 100644 index 000000000..d0f20165c --- /dev/null +++ b/sys/src/cmd/aux/usbsdmux.c @@ -0,0 +1,112 @@ +#include <u.h> +#include <libc.h> + +enum { + I2C_ADDR = 0x41, + + REG_INPUT = 0x00, + REG_OUTPUT = 0x01, + REG_POLARITY = 0x02, + REG_CONFIG = 0x03, + + IO_DAT = 1<<0, + IO_PWR = 1<<1, + IO_DUT = 1<<2, + IO_CARD = 1<<3, +}; + +enum { + MODE_OFF, + MODE_DUT, + MODE_HOST, +}; + +int mode, fd; +char *file = "/dev/sdUdca10/raw"; + +void +wr(int reg, int val) +{ + static uchar cmd[16], dat[512]; + char status[32]; + int n; + + cmd[0] = 0xCF; + cmd[1] = 0x23; + cmd[2] = I2C_ADDR<<1; + cmd[3] = 0; + cmd[4] = 2>>8; + cmd[5] = 2; + cmd[6] = 0; + + if(write(fd, cmd, sizeof(cmd)) != sizeof(cmd)) + sysfatal("write command: %r"); + + dat[0] = reg; + dat[1] = val; + if(write(fd, dat, sizeof(dat)) < 0) + sysfatal("write data: %r"); + + if((n = pread(fd, status, sizeof(status)-1, 0)) < 0) + sysfatal("read status: %r"); + + status[n] = '\0'; + if(atoi(status) != 0) + sysfatal("command error status: %s", status); +} + +void +usage(void) +{ + fprint(2, "usage: %s off|dut|host [/dev/sdUxxxxx/raw]\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + ARGBEGIN { + } ARGEND; + + switch(argc){ + case 2: + file = argv[1]; + /* no break */ + case 1: + break; + default: + usage(); + } + + if(cistrcmp(argv[0], "off") == 0) + mode = MODE_OFF; + else if(cistrcmp(argv[0], "dut") == 0) + mode = MODE_DUT; + else if(cistrcmp(argv[0], "host") == 0) + mode = MODE_HOST; + else + usage(); + + if((fd = open(file, ORDWR)) < 0) + sysfatal("open: %r"); + + /* disconnect mode */ + wr(REG_OUTPUT, IO_DAT|IO_PWR|IO_DUT|IO_CARD); + wr(REG_CONFIG, 0); + sleep(100); + + /* apply mode */ + switch(mode){ + case MODE_OFF: + break; + case MODE_DUT: + wr(REG_OUTPUT, IO_DAT|IO_PWR|IO_CARD); + wr(REG_OUTPUT, IO_DUT|IO_CARD); + break; + case MODE_HOST: + wr(REG_OUTPUT, 0); + break; + } + + exits(nil); +} |