shithub: front

Download patch

ref: 0ed2a4996372cce1b3212c0640a7967fb0435f77
parent: 2a37d342f2e8741065fdd81ab850e110aaa7556a
author: mia soweli <mia@soweli.net>
date: Sat Aug 9 13:30:16 EDT 2025

i2cdwc: implement init

--- a/sys/src/9/pc/i2cdwc.c
+++ b/sys/src/9/pc/i2cdwc.c
@@ -13,10 +13,24 @@
 #include "../port/i2c.h"
 
 enum {
-	Rctrl = 0x00,
+	/* control */
+	Rcon = 0x00,
 	Raddrtarget = 0x04,
 	Raddr = 0x08,
 	Rdata = 0x10,
+	Renable = 0x6c,
+
+	/* timing */
+	Rsclhss = 0x14,
+	Rscllss = 0x18,
+	Rsclhfs = 0x1c,
+	Rscllfs = 0x20,
+
+	/* fifo */
+	Rfiforxthresh = 0x38,
+	Rfifotxthresh = 0x3c,
+
+	/* interrupt */
 	Rintr = 0x2c,
 	Rintrmask = 0x30,
 	Rintrclear = 0x40,
@@ -29,10 +43,22 @@
 	Rintrclearact = 0x5c,
 	Rintrcleardetstop = 0x60,
 	Rintrcleardetstart = 0x64,
+
+	/* component */
+	Rcompparam = 0xf4,
 	Rcompver = 0xf8,
 	Rcomptype = 0xfc,
 };
 
+enum {
+	/* control */
+	Ccontroller = 1<<0,
+	Cspeed = 1<<1,
+	Cspeedfast = 1<<2,
+	Crestart = 1<<5,
+	Ctargetdisable = 1<<6,
+};
+
 typedef struct Ctlr Ctlr;
 struct Ctlr {
 	Rendez;
@@ -41,6 +67,14 @@
 
 	u64int port;
 	u32int *portmmio;
+
+	u32int sclhss;
+	u32int scllss;
+	u32int sclhfs;
+	u32int scllfs;
+
+	u8int fifotx;
+	u8int fiforx;
 };
 
 static Ctlr *i2cdwcctlr;
@@ -49,10 +83,54 @@
 #define csr32r(c, r) (*((c)->portmmio+((r)/4)))
 #define csr32w(c, r, v) (*((c)->portmmio+((r)/4)) = (v))
 
+static void
+i2cdwcenable(Ctlr *c, int e)
+{
+	int r;
+
+	for(r = 0; r < 100; r++){
+		csr32w(c, Renable, e);
+		if ((csr32r(c, Renable) & 1) == e)
+			return;
+
+		microdelay(25);
+	}
+
+	error("timeout wating for enable");
+}
+
 static int
-i2cdwcinit(I2Cbus *)
+i2cdwcinit(I2Cbus *b)
 {
-	/* XXX: init */
+	Ctlr *c;
+
+	c = b->ctlr;
+	if(csr32r(c, Rcomptype) != 0x44570140)
+		error("invalid component");
+
+	/* read timing parameters */
+	c->sclhss = csr32r(c, Rsclhss);
+	c->scllss = csr32r(c, Rscllss);
+	c->sclhfs = csr32r(c, Rsclhfs);
+	c->scllfs = csr32r(c, Rscllfs);
+
+	/* read fifo parameters */
+	c->fifotx = csr32r(c, Rcompparam) >> 16;
+	c->fiforx = csr32r(c, Rcompparam) >> 8;
+	i2cdwcenable(c, 0);
+
+	/* write timing parameters */
+	csr32w(c, Rsclhss, c->sclhss);
+	csr32w(c, Rscllss, c->scllss);
+	csr32w(c, Rsclhfs, c->sclhfs);
+	csr32w(c, Rscllfs, c->scllfs);
+
+	/* write fifo parameters */
+	csr32w(c, Rfifotxthresh, c->fifotx / 2);
+	csr32w(c, Rfiforxthresh, 0);
+
+	/* configure */
+	csr32w(c, Rcon, Ccontroller | Cspeedfast | Crestart | Ctargetdisable);
 	return 0;
 }
 
--