shithub: util

Download patch

ref: 284d1ce2d7f4992ef2edee3eaaeeecca70e535cd
parent: 7ad5e3ef8905ce04b9cdb3dca8e11732ec932ba9
author: glenda <glenda@kingship>
date: Fri Oct 17 19:26:07 EDT 2025

mcp7940x oscillator trim register

--- a/mcp7940x.c
+++ b/mcp7940x.c
@@ -20,6 +20,10 @@
 	Year=		6,
 	Nbcd=		7,
 
+	Control=	7,
+		CrsTrim=	1<<2,
+	OscTrim=	8,
+
 	/* Hours register may be in 12-hour or 24-hour mode */
 	Twelvehr=	0x40,
 	Pm=			0x20,
@@ -184,10 +188,12 @@
 	char buf[256];
 	ulong t;
 	char *data;
+	int sign;
+	int trim;
 
 	clk[0] = 0;
 
-	if ((intptr)(r->fid->file->aux) == 173) {
+	if ((intptr)(r->fid->file->aux) == 1) {
 		data = smprint(DATA, i2cdir);
 		if (data == nil)
 			sysfatal("smprint: %r");
@@ -220,6 +226,32 @@
 		snprint(buf, 256, "%12lud", t);
 		readstr(r, buf);
 		respond(r, nil);
+	} else if ((intptr)(r->fid->file->aux) == 2) {
+		data = smprint(DATA, i2cdir);
+		if (data == nil)
+			sysfatal("smprint: %r");
+		fd = open(data, ORDWR);
+		if (fd < 0)
+			sysfatal("open: %r");
+		free(data);
+
+		clk[0] = OscTrim;
+		write(fd, clk, 1);
+		read(fd, clk, 1);
+		close(fd);
+
+		sign = 1;
+		if ((clk[0] & 0x80) == 0) {
+			sign = -1;
+		}
+
+		trim = clk[0] & 0x7F;
+		trim <<= 1;
+		trim *= sign;
+
+		snprint(buf, 256, "%12d", trim);
+		readstr(r, buf);
+		respond(r, nil);
 	} else {
 		respond(r, "file not found");
 	}
@@ -232,12 +264,15 @@
 {
 	Rtc rtc;
 	ulong secs;
+	int sign;
 	uchar bcdclock[1+Nbcd];
 	char *p, *ep;
 	int fd;
 	char *data;
+	long trim;
+	uchar reg[2];
 
-	if ((intptr)(r->fid->file->aux) == 173) {
+	if ((intptr)(r->fid->file->aux) == 1) {
 		p = r->ifcall.data;
 		ep = p + r->ifcall.count;
 
@@ -273,6 +308,45 @@
 		close(fd);
 
 		respond(r, nil);
+	} else if ((intptr)(r->fid->file->aux) == 2) {
+		p = r->ifcall.data;
+		ep = p + r->ifcall.count;
+
+		sign = 1;
+		while(p < ep) {
+			if (*p == '-')
+				sign = -1;
+			else if (*p >= '0' && *p <= '9')
+				break;
+			p++;
+		}
+
+		trim = strtol(p, 0, 0);
+		if (trim < 0 || trim > 254) {
+			respond(r, "invalid trim value");
+			return;
+		}
+
+		trim >>= 1;
+
+		reg[0] = OscTrim;
+		reg[1] = 0;
+		if (sign == 1)
+			reg[1] = 0x80;
+		reg[1] |= (uchar)trim;
+
+		data = smprint(DATA, i2cdir);
+		if (data == nil)
+			sysfatal("smprint: %r");
+		fd = open(data, ORDWR);
+		if (fd < 0)
+			sysfatal("open: %r");
+		free(data);
+
+		if (write(fd, reg, 2) != 2)
+			sysfatal("write: %r");
+
+		close(fd);
 	} else {
 		respond(r, "file not found");
 	}
@@ -286,10 +360,35 @@
 void
 main()
 {
+	char *data;
+	int fd;
+	uchar reg;
+	uchar buf[2];
+
 	ctl("size 10");
 	ctl("subaddress 0");
 
+	data = smprint(DATA, i2cdir);
+	if (data == nil)
+		sysfatal("smprint: %r");
+	fd = open(data, ORDWR);
+	if (fd < 0)
+		sysfatal("open: %r");
+	free(data);
+	reg = Control;
+	if (write(fd, &reg, 1) != 1)
+		sysfatal("write: %r");
+	if (read(fd, &reg, 1) != 1)
+		sysfatal("read: %r");
+	reg |= CrsTrim;
+	buf[0] = Control;
+	buf[1] = reg;
+	if (write(fd, buf, 2) != 2)
+		sysfatal("write: %r");
+	close(fd);
+
 	fs.tree = alloctree("mcp7940x", "mcp7940x", DMDIR|0555, nil);
-	createfile(fs.tree->root, "rtc", "mcp7940x", 0666, (void*)173);
+	createfile(fs.tree->root, "rtc", "mcp7940x", 0666, (void*)1);
+	createfile(fs.tree->root, "rtctrim", "mcp7940x", 0666, (void*)2);
 	postmountsrv(&fs, "mcp7940x", "/dev", MBEFORE);
 }
--