shithub: front

Download patch

ref: 2a37d342f2e8741065fdd81ab850e110aaa7556a
parent: 67b05da8331d8693b7e1e2f3c5acadb78458ca3d
author: mia soweli <mia@soweli.net>
date: Sat Aug 9 06:35:52 EDT 2025

i2cdwc: add synopsys designware i²c driver

--- /dev/null
+++ b/sys/src/9/pc/i2cdwc.c
@@ -1,0 +1,272 @@
+/*
+ * synopsys designware core i²c driver
+ */
+
+#include "u.h"
+#include "../port/lib.h"
+#include "../port/error.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/pci.h"
+#include "../port/i2c.h"
+
+enum {
+	Rctrl = 0x00,
+	Raddrtarget = 0x04,
+	Raddr = 0x08,
+	Rdata = 0x10,
+	Rintr = 0x2c,
+	Rintrmask = 0x30,
+	Rintrclear = 0x40,
+	Rintrclearrxunder = 0x44,
+	Rintrclearrxover = 0x48,
+	Rintrcleartxover = 0x4c,
+	Rintrclearrdreq = 0x50,
+	Rintrcleartxabrt = 0x54,
+	Rintrclearrxdone = 0x58,
+	Rintrclearact = 0x5c,
+	Rintrcleardetstop = 0x60,
+	Rintrcleardetstart = 0x64,
+	Rcompver = 0xf8,
+	Rcomptype = 0xfc,
+};
+
+typedef struct Ctlr Ctlr;
+struct Ctlr {
+	Rendez;
+
+	Ctlr *link;
+
+	u64int port;
+	u32int *portmmio;
+};
+
+static Ctlr *i2cdwcctlr;
+static Ctlr *i2cdwcctlrtail;
+
+#define csr32r(c, r) (*((c)->portmmio+((r)/4)))
+#define csr32w(c, r, v) (*((c)->portmmio+((r)/4)) = (v))
+
+static int
+i2cdwcinit(I2Cbus *)
+{
+	/* XXX: init */
+	return 0;
+}
+
+static int
+i2cdwcio(I2Cdev *, uchar *, int, int)
+{
+	/* XXX: io */
+	return 0;
+}
+
+static void
+i2cdwcpnp(void)
+{
+	/* XXX: acpi :( */
+}
+
+static void
+i2cdwcpnppci(void)
+{
+	Ctlr *c;
+	Pcidev *p;
+
+	for(p = nil; p = pcimatch(p, 0x8086, 0);){
+		if(p->ccrb != 0x0c || p->ccru != 0x80)
+			continue;
+		if(p->mem[0].bar & 1)
+			continue;
+
+		switch(p->did){
+		case 0xa160: /* intel 100 series */
+		case 0xa161:
+		case 0xa162:
+		case 0xa163:
+		case 0x9d60: /* intel 100 series lp */
+		case 0x9d61:
+		case 0x9d62:
+		case 0x9d63:
+		case 0x9d64:
+		case 0x9d65:
+		case 0xa2e0: /* intel 200 series */
+		case 0xa2e1:
+		case 0xa2e2:
+		case 0xa2e3:
+		case 0xa368: /* intel 300 series */
+		case 0xa369:
+		case 0xa36a:
+		case 0xa36b:
+		case 0x9dc5: /* intel 300 series u */
+		case 0x9dc6:
+		case 0x9de8:
+		case 0x9de9:
+		case 0x9dea:
+		case 0x9deb:
+		case 0x06e8: /* intel 400 series */
+		case 0x06e9:
+		case 0x06ea:
+		case 0x06eb:
+		case 0x02c5: /* intel 400 series lp */
+		case 0x02c6:
+		case 0x02e8:
+		case 0x02e9:
+		case 0x02ea:
+		case 0x02eb:
+		case 0xa3e0: /* intel 400 series v */
+		case 0xa3e1:
+		case 0xa3e2:
+		case 0xa3e3:
+		case 0x34e8: /* intel 495 series lp */
+		case 0x34e9:
+		case 0x34ea:
+		case 0x34eb:
+		case 0x34c5:
+		case 0x34c6:
+		case 0x43e8: /* intel 500 series */
+		case 0x43e9:
+		case 0x43ea:
+		case 0x43eb:
+		case 0x43ad:
+		case 0x43ae:
+		case 0x43d8:
+		case 0xa0c5: /* intel 500 series lp */
+		case 0xa0c6:
+		case 0xa0e8:
+		case 0xa0e9:
+		case 0xa0ae:
+		case 0xa0eb:
+		case 0x7acc: /* intel 600 series */
+		case 0x7acd:
+		case 0x7ace:
+		case 0x7acf:
+		case 0x7afc:
+		case 0x7afd:
+		case 0x51c5: /* intel 600 series lp */
+		case 0x51c6:
+		case 0x51d8:
+		case 0x51d9:
+		case 0x51e8:
+		case 0x51e9:
+		case 0x51ea:
+		case 0x51eb:
+		case 0x7a4c: /* intel 700 series */
+		case 0x7a4d:
+		case 0x7a4e:
+		case 0x7a4f:
+		case 0x7a7c:
+		case 0x7a7d:
+		case 0x5aac: /* intel apollo lake */
+		case 0x5aae:
+		case 0x5ab0:
+		case 0x5ab2:
+		case 0x5ab4:
+		case 0x5ab6:
+		case 0x5ab8:
+		case 0x5aba:
+		case 0x31ac: /* intel gemini lake */
+		case 0x31ae:
+		case 0x31b0:
+		case 0x31b2:
+		case 0x31b4:
+		case 0x31b6:
+		case 0x31b8:
+		case 0x31ba:
+		case 0x4de8: /* intel jasper lake */
+		case 0x4de9:
+		case 0x4dea:
+		case 0x4deb:
+		case 0x4dc5:
+		case 0x4dc6:
+		case 0x4b78: /* intel elkhart lake */
+		case 0x4b79:
+		case 0x4b7a:
+		case 0x4b7b:
+		case 0x4b4b:
+		case 0x4b4c:
+		case 0x4b44:
+		case 0x4b45:
+		case 0x54e8: /* intel alder lake */
+		case 0x54e9:
+		case 0x54ea:
+		case 0x54eb:
+		case 0x54c5:
+		case 0x54c6:
+		case 0x54d8:
+		case 0x54d9:
+		case 0x7e78: /* intel metor lake */
+		case 0x7e79:
+		case 0x7e7a:
+		case 0x7e7b:
+		case 0x7e50:
+		case 0x7e51:
+		case 0xa878: /* intel lunar lake */
+		case 0xa879:
+		case 0xa87a:
+		case 0xa87b:
+		case 0xa850:
+		case 0xa851:
+			break;
+		default:
+			continue;
+		}
+
+		c = malloc(sizeof(*c));
+		if(c == nil) {
+			print("#J: dwc: no memory for ctlr");
+			continue;
+		}
+
+		c->port = p->mem[0].bar & ~0xf;
+		c->portmmio = vmap(c->port, p->mem[0].size);
+		if(c->portmmio == nil){
+			print("#J: dwc: no memory for ctlr mmio");
+			free(c);
+			continue;
+		}
+
+		pcienable(p);
+
+		if(i2cdwcctlr == nil)
+			i2cdwcctlr = c;
+		else
+			i2cdwcctlrtail->link = c;
+		i2cdwcctlrtail = c;
+	}
+}
+
+void
+i2cdwclink(void)
+{
+	Ctlr *c;
+	I2Cbus *bus;
+	int busno;
+
+	busno = 0;
+
+	i2cdwcpnp();
+	i2cdwcpnppci();
+	for(c = i2cdwcctlr; c != nil; c = c->link) {
+		bus = malloc(sizeof(*bus));
+		if(bus == nil){
+			print("#J: dwc: no memory for bus");
+			continue;
+		}
+
+		bus->name = malloc(KNAMELEN);
+		if(bus->name == nil){
+			print("#J: dwc: no memory for bus name");
+			free(bus);
+			continue;
+		}
+
+		snprint(bus->name, KNAMELEN, "i2c%d", busno++);
+		bus->ctlr = c;
+		bus->init = i2cdwcinit;
+		bus->io = i2cdwcio;
+		addi2cbus(bus);
+	}
+}
--- a/sys/src/9/pc/pc
+++ b/sys/src/9/pc/pc
@@ -38,6 +38,7 @@
 	i82365		cis
 	uart
 	usb
+	i2c
 	
 	segment
 	vmx
@@ -94,6 +95,8 @@
 	audiohda	pci
 
 	pmmc		pci
+
+	i2cdwc		pci devi2c
 
 misc
 	pci		pcipc pcibios bios32
--- a/sys/src/9/pc64/pc64
+++ b/sys/src/9/pc64/pc64
@@ -37,6 +37,7 @@
 #	i82365		cis
 	uart
 	usb
+	i2c
 	
 	segment
 	vmx
@@ -94,6 +95,8 @@
 	audiohda	pci
 
 	pmmc		pci
+
+	i2cdwc		pci devi2c
 
 misc
 	pci		pcipc
--