summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2022-10-09 12:12:13 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2022-10-09 12:12:13 +0000
commita3f3953ab2f245cd47aab3563014c04f1a70f9be (patch)
treed41fef4bdbf207b7c5cf9d8b9568b85cf5a4ea30 /sys/src
parent610071bb8b28fe8a871b97f0332e47c3d921f3cf (diff)
usbsdmux: Add program to control usb-sd-mux device
Diffstat (limited to 'sys/src')
-rw-r--r--sys/src/cmd/aux/mkfile1
-rw-r--r--sys/src/cmd/aux/usbsdmux.c112
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);
+}