long gpioread(Chan *c, void *va, long n, vlong off) { int type, scheme; uint pin; char *a; a = va; if(c->qid.type & QTDIR) { return devdirread(c, va, n, 0, 0, gpiogen); } type = FILE_TYPE(c->qid); scheme = SCHEME_TYPE(c->qid); if(scheme != Qgeneric && scheme != pinscheme) { error(nil); } switch(type) { case Qdata: pin = PIN_NUMBER(c->qid); a[0] = (gpioin(pin))?'1':'0'; n = 1; break; case Qctl: break; case Qevent: if(off >= 4) { off %= 4; eventvalue = 0; } sleep(&rend, isset, 0); if(off + n > 4) { n = 4 - off; } memmove(a, &eventvalue + off, n); } return n; }
static void adm_read(int cs, char *buf, unsigned int bits) { int i, len = (bits + 7) / 8; __u8 mask; gpioout(eecs, (cs ? eecs : 0)); udelay(EECK_EDGE_TIME); /* Byte assemble from MSB to LSB */ for (i = 0; i < len; i++) { __u8 byte; /* Bit bang from MSB to LSB */ for (mask = 0x80, byte = 0; mask && bits > 0; mask >>= 1, bits --) { __u8 gp; /* Clock low */ gpioout(eesk, 0); udelay(EECK_EDGE_TIME); /* Input on rising edge */ gp = gpioin(); if (gp & eedi) byte |= mask; /* Clock high */ gpioout(eesk, eesk); udelay(EECK_EDGE_TIME); } *buf++ = byte; } /* Clock low */ gpioout(eesk, 0); udelay(EECK_EDGE_TIME); if (cs) gpioout(eecs, 0); }