ref: a3f2d6d23ed1be69fee607bdedadc0438fd01305
dir: /sys/src/cmd/nusb/serial/silabs.c/
#include <u.h> #include <libc.h> #include <thread.h> #include <fcall.h> #include <9p.h> #include "usb.h" #include "serial.h" enum { Enable = 0x00, Getbaud = 0x1D, Setbaud = 0x1E, Setlcr = 0x03, Getlcr = 0x04, Bitsmask = 0x0F00, Bitsshift = 8, Parmask = 0x00F0, Parshift = 4, Stopmask = 0x000F, Stop1 = 0x0000, Stop1_5 = 0x0001, Stop2 = 0x0002, }; static Cinfo slinfo[] = { { 0x10c4, 0xea60, }, /* CP210x */ { 0x10c4, 0xea61, }, /* CP210x */ { 0, 0, }, }; static Serialops slops; slprobe(Serial *ser) { Usbdev *ud = ser->dev->usb; if(matchid(slinfo, ud->vid, ud->did) == nil) return -1; ser->Serialops = slops; return 0; } static int slwrite(Serialport *p, int req, void *buf, int len) { Serial *ser; ser = p->s; return usbcmd(ser->dev, Rh2d | Rvendor | Riface, req, 0, p->interfc, buf, len); } static int slput(Serialport *p, uint op, uint val) { Serial *ser; ser = p->s; return usbcmd(ser->dev, Rh2d | Rvendor | Riface, op, val, p->interfc, nil, 0); } static int slread(Serialport *p, int req, void *buf, int len) { Serial *ser; ser = p->s; return usbcmd(ser->dev, Rd2h | Rvendor | Riface, req, 0, p->interfc, buf, len); } static int slinit(Serialport *p) { Serial *ser; ser = p->s; dsprint(2, "slinit\n"); slput(p, Enable, 1); slops.getparam(p); /* p gets freed by closedev, the process has a reference */ incref(ser->dev); return 0; } static int slgetparam(Serialport *p) { u16int lcr; slread(p, Getbaud, &p->baud, sizeof(p->baud)); slread(p, Getlcr, &lcr, sizeof(lcr)); p->bits = (lcr&Bitsmask)>>Bitsshift; p->parity = (lcr&Parmask)>>Parshift; p->stop = (lcr&Stopmask) == Stop1? 1 : 2; return 0; } static int slsetparam(Serialport *p) { u16int lcr; lcr = p->stop == 1? Stop1 : Stop2; lcr |= (p->bits<<Bitsshift) | (p->parity<<Parshift); slput(p, Setlcr, lcr); slwrite(p, Setbaud, &p->baud, sizeof(p->baud)); return 0; } static int wait4data(Serialport *p, uchar *data, int count) { int n; qunlock(p->s); while ((n = read(p->epin->dfd, data, count)) == 0) ; qlock(p->s); return n; } static Serialops slops = { .init = slinit, .getparam = slgetparam, .setparam = slsetparam, .wait4data = wait4data, };