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