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;
}
--
⑨