1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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);
}
|