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\