code: plan9front

Download patch

ref: 9e8fc02528d531c922e75395b5a7037904445d4b
parent: e55b6a5aff9788b1606a56c3666ecdc87f1712c3
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Aug 8 15:57:06 EDT 2022

imx8: add aux/imx8pm with lcd brightness control

--- a/sys/src/9/imx8/lcd.c
+++ b/sys/src/9/imx8/lcd.c
@@ -834,6 +834,19 @@
 	gpioout(GPIO_PIN(1, 10), blank == 0);
 }
 
+static void
+lcdmeminit(void)
+{
+	Physseg seg;
+
+	memset(&seg, 0, sizeof seg);
+	seg.attr = SG_PHYSICAL | SG_DEVICE | SG_NOEXEC;
+	seg.name = "pwm2";
+	seg.pa = (uintptr)pwm2 - KZERO;
+	seg.size = BY2PG;
+	addphysseg(&seg);
+}
+
 void
 lcdinit(void)
 {
@@ -913,6 +926,9 @@
 		err = "screeninit failed";
 		goto out;
 	}
+
+	/* expose useful segment(s) to the userspace */
+	lcdmeminit();
 
 	/* start the pixel clock */
 	setclkrate("lcdif.pix_clk", "system_pll1_clk", mode.pixclk);
--- /dev/null
+++ b/sys/src/cmd/aux/imx8pm.c
@@ -1,0 +1,124 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+enum
+{
+	Mhz = 1000*1000,
+	Pwmsrcclk = 25*Mhz,
+	Ctl = 1,
+
+	PWMSAR = 0x0C/4,
+	PWMPR = 0x10/4,
+};
+
+static u32int *pwm2;
+static char *uid = "mntpm";
+
+static void
+wr(u32int *base, int reg, u32int v)
+{
+	base[reg] = v;
+}
+
+static u32int
+rd(u32int *base, int reg)
+{
+	return base[reg];
+}
+
+static void
+setbrightness(int p)
+{
+	u32int v;
+
+	if(p < 0)
+		p = 0;
+	if(p > 100)
+		p = 100;
+
+	v = Pwmsrcclk / rd(pwm2, PWMSAR);
+	wr(pwm2, PWMPR, (Pwmsrcclk/(v*p/100))-2);
+}
+
+static void
+fsread(Req *r)
+{
+	u32int m, v;
+	char msg[256];
+
+	if(r->fid->file->aux == (void*)Ctl){
+		m = Pwmsrcclk / rd(pwm2, PWMSAR);
+		v = Pwmsrcclk / (rd(pwm2, PWMPR)+2);
+		snprint(msg, sizeof(msg), "brightness %d\n", v*100/m);
+		readstr(r, msg);
+	}
+	respond(r, nil);
+}
+
+static void
+fswrite(Req *r)
+{
+	char msg[256], *f[4];
+	int nf;
+
+	if(r->fid->file->aux == (void*)Ctl){
+		snprint(msg, sizeof(msg), "%.*s",
+			utfnlen((char*)r->ifcall.data, r->ifcall.count), (char*)r->ifcall.data);
+		nf = tokenize(msg, f, nelem(f));
+		if(nf < 2){
+			respond(r, "invalid ctl message");
+			return;
+		}
+		if(strcmp(f[0], "brightness") == 0)
+			setbrightness(atoi(f[1]));
+	}
+
+	r->ofcall.count = r->ifcall.count;
+	respond(r, nil);
+}
+
+static Srv fs = {
+	.read = fsread,
+	.write = fswrite,
+};
+
+static void
+usage(void)
+{
+	fprint(2, "usage: aux/imx8pm [-D] [-m /mnt/pm] [-s service]\n");
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	char *mtpt, *srv;
+
+	mtpt = "/mnt/pm";
+	srv = nil;
+	ARGBEGIN{
+	case 'D':
+		chatty9p = 1;
+		break;
+	case 'm':
+		mtpt = EARGF(usage());
+		break;
+	case 's':
+		srv = EARGF(usage());
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	if((pwm2 = segattach(0, "pwm2", 0, 0x18)) == (void*)-1)
+		sysfatal("pwm2");
+
+	fs.tree = alloctree(uid, uid, DMDIR|0555, nil);
+	createfile(fs.tree->root, "ctl", uid, 0666, (void*)Ctl);
+	postmountsrv(&fs, srv, mtpt, MREPL);
+
+	exits(nil);
+}
--- a/sys/src/cmd/aux/mkfile
+++ b/sys/src/cmd/aux/mkfile
@@ -22,6 +22,7 @@
 	getflags\
 	icanhasmsi\
 	icanhasvmx\
+	imx8pm\
 	lines\
 	listen\
 	listen1\