ref: 354273938c80121158db1a9ac87556ddcb1d024c
parent: 86b470d877870dd1c48f57d98586b48278cd9b5c
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Sep 16 19:35:33 EDT 2023
devi2c: expose the I2Cdev structure to the controller. some i2c controllers might be rather constrained and need information like the sub-address size, which is contained in the I2Cdev structure, so pass that to the bus->io function instead of the I2Cbus pointer.
--- a/sys/src/9/imx8/i2cimx.c
+++ b/sys/src/9/imx8/i2cimx.c
@@ -83,8 +83,9 @@
static uchar dummy;
static int
-io(I2Cbus *bus, uchar *pkt, int olen, int ilen)
+io(I2Cdev *dev, uchar *pkt, int olen, int ilen)
{
+ I2Cbus *bus = dev->bus;
Ctlr *ctlr = bus->ctlr;
uchar *regs = ctlr->regs;
int cr, sr, alen, o, i;
--- a/sys/src/9/imx8/mkfile
+++ b/sys/src/9/imx8/mkfile
@@ -89,6 +89,7 @@
main.$O: rebootcode.i
+i2cimx.$O: ../port/i2c.h
pciimx.$O: ../port/pci.h
usbxhciimx.$O: ../port/usbxhci.h
--- a/sys/src/9/port/devi2c.c
+++ b/sys/src/9/port/devi2c.c
@@ -125,8 +125,9 @@
}
int
-i2cbusio(I2Cbus *bus, uchar *pkt, int olen, int ilen)
+i2cbusio(I2Cdev *dev, uchar *pkt, int olen, int ilen)
{
+ I2Cbus *bus = dev->bus;
int user, n;
user = enterbus(bus);
@@ -135,12 +136,12 @@
return -1;
}
if(user && waserror()){
- (*bus->io)(bus, nil, 0, 0);
+ (*bus->io)(dev, nil, 0, 0);
leavebus(bus);
nexterror();
}
// iprint("%s: <- %.*H\n", bus->name, olen, pkt);
- n = (*bus->io)(bus, pkt, olen, ilen);
+ n = (*bus->io)(dev, pkt, olen, ilen);
// if(n > olen) iprint("%s: -> %.*H\n", bus->name, n - olen, pkt+olen);
leavebus(bus);
@@ -181,7 +182,7 @@
if(len > 0)
memmove(pkt+o, data, len);
- return i2cbusio(dev->bus, pkt, o + len, 0) - o;
+ return i2cbusio(dev, pkt, o + len, 0) - o;
}
int
@@ -194,7 +195,7 @@
if(o+len > sizeof(pkt))
len = sizeof(pkt)-o;
- len = i2cbusio(dev->bus, pkt, o, len) - o;
+ len = i2cbusio(dev, pkt, o, len) - o;
if(len > 0)
memmove(data, pkt+o, len);
@@ -206,7 +207,7 @@
{
uchar pkt[2];
int o = putaddr(dev, rw, pkt, -1);
- if(i2cbusio(dev->bus, pkt, o, 0) != o)
+ if(i2cbusio(dev, pkt, o, 0) != o)
return -1;
return rw != 0;
}
@@ -215,7 +216,7 @@
{
uchar pkt[2+1];
int o = putaddr(dev, 1, pkt, -1);
- if(i2cbusio(dev->bus, pkt, o, 1) - o != 1)
+ if(i2cbusio(dev, pkt, o, 1) - o != 1)
return -1;
return pkt[o];
}
@@ -225,7 +226,7 @@
uchar pkt[2+1];
int o = putaddr(dev, 0, pkt, -1);
pkt[o] = b;
- if(i2cbusio(dev->bus, pkt, o+1, 0) - o != 1)
+ if(i2cbusio(dev, pkt, o+1, 0) - o != 1)
return -1;
return b;
}
@@ -234,7 +235,7 @@
{
uchar pkt[2+4+1];
int o = putaddr(dev, 1, pkt, addr);
- if(i2cbusio(dev->bus, pkt, o, 1) - o != 1)
+ if(i2cbusio(dev, pkt, o, 1) - o != 1)
return -1;
return pkt[o];
}
@@ -244,7 +245,7 @@
uchar pkt[2+4+1];
int o = putaddr(dev, 0, pkt, addr);
pkt[o] = b;
- if(i2cbusio(dev->bus, pkt, o+1, 0) - o != 1)
+ if(i2cbusio(dev, pkt, o+1, 0) - o != 1)
return -1;
return b;
}
@@ -253,7 +254,7 @@
{
uchar pkt[2+4+2];
int o = putaddr(dev, 1, pkt, addr);
- if(i2cbusio(dev->bus, pkt, o, 2) - o != 2)
+ if(i2cbusio(dev, pkt, o, 2) - o != 2)
return -1;
return pkt[o] | (ushort)pkt[o+1]<<8;
}
@@ -264,7 +265,7 @@
int o = putaddr(dev, 0, pkt, addr);
pkt[o+0] = w;
pkt[o+1] = w>>8;
- if(i2cbusio(dev->bus, pkt, o+2, 0) - o != 2)
+ if(i2cbusio(dev, pkt, o+2, 0) - o != 2)
return -1;
return w;
}
@@ -273,7 +274,7 @@
{
uchar pkt[2+4+4];
int o = putaddr(dev, 1, pkt, addr);
- if(i2cbusio(dev->bus, pkt, o, 4) - o != 4)
+ if(i2cbusio(dev, pkt, o, 4) - o != 4)
return -1;
return pkt[o] | (ulong)pkt[o+1]<<8 | (ulong)pkt[o+2]<<16 | (ulong)pkt[o+3]<<24;
}
@@ -286,7 +287,7 @@
pkt[o+1] = u>>8;
pkt[o+2] = u>>16;
pkt[o+3] = u>>24;
- if(i2cbusio(dev->bus, pkt, o+4, 0) - o != 4)
+ if(i2cbusio(dev, pkt, o+4, 0) - o != 4)
return -1;
return u;
}
@@ -329,11 +330,11 @@
if(i2cdev(bus, dummy.addr) != nil)
continue;
if(user && waserror()){
- (*bus->io)(bus, nil, 0, 0);
+ (*bus->io)(&dummy, nil, 0, 0);
continue;
}
n = putaddr(&dummy, 0, pkt, -1);
- if((*bus->io)(bus, pkt, n, 0) == n)
+ if((*bus->io)(&dummy, pkt, n, 0) == n)
probeddev(&dummy);
if(user) poperror();
}
@@ -343,11 +344,11 @@
if(i2cdev(bus, dummy.addr) != nil)
continue;
if(user && waserror()){
- (*bus->io)(bus, nil, 0, 0);
+ (*bus->io)(&dummy, nil, 0, 0);
continue;
}
n = putaddr(&dummy, 0, pkt, -1);
- if((*bus->io)(bus, pkt, n, 0) == n)
+ if((*bus->io)(&dummy, pkt, n, 0) == n)
probeddev(&dummy);
if(user) poperror();
}
--- a/sys/src/9/port/i2c.h
+++ b/sys/src/9/port/i2c.h
@@ -1,4 +1,6 @@
typedef struct I2Cbus I2Cbus;
+typedef struct I2Cdev I2Cdev;
+
struct I2Cbus
{
char *name;
@@ -6,13 +8,12 @@
void *ctlr;
int (*init)(I2Cbus *bus);
- int (*io)(I2Cbus *bus, uchar *pkt, int olen, int ilen);
+ int (*io)(I2Cdev *dev, uchar *pkt, int olen, int ilen);
int probed;
QLock;
};
-typedef struct I2Cdev I2Cdev;
struct I2Cdev
{
I2Cbus *bus;
@@ -38,7 +39,7 @@
/*
* generic I/O
*/
-extern int i2cbusio(I2Cbus *bus, uchar *pkt, int olen, int ilen);
+extern int i2cbusio(I2Cdev *dev, uchar *pkt, int olen, int ilen);
extern int i2crecv(I2Cdev *dev, void *data, int len, vlong addr);
extern int i2csend(I2Cdev *dev, void *data, int len, vlong addr);