From 5a3aea0ca8fc8ec5529a5328e6f7879ad6d976da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sigrid=20Solveig=20Hafl=C3=ADnud=C3=B3ttir?= Date: Wed, 7 Sep 2022 00:52:49 +0000 Subject: imx8/pm: provide acpi(1)-compatible battery readings --- sys/src/9/imx8/main.c | 25 +++++++++ sys/src/cmd/reform/pm.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 167 insertions(+), 2 deletions(-) (limited to 'sys/src') diff --git a/sys/src/9/imx8/main.c b/sys/src/9/imx8/main.c index 471d15294..3ccd91ee1 100644 --- a/sys/src/9/imx8/main.c +++ b/sys/src/9/imx8/main.c @@ -265,6 +265,30 @@ tmuinit(void) addphysseg(&seg); } +static void +lpcspiinit(void) +{ + Physseg seg; + + iomuxpad("pad_ecspi2_sclk", "ecspi2_sclk", "~LVTTL ~HYS ~PUE ~ODE FAST 45_OHM"); + iomuxpad("pad_ecspi2_mosi", "ecspi2_mosi", "~LVTTL ~HYS ~PUE ~ODE FAST 45_OHM"); + iomuxpad("pad_ecspi2_miso", "ecspi2_miso", "~LVTTL ~HYS ~PUE ~ODE FAST 45_OHM"); + iomuxpad("pad_ecspi2_ss0", "ecspi2_ss0", "~LVTTL ~HYS ~PUE ~ODE FAST 45_OHM"); + + setclkgate("ecspi2.ipg_clk", 0); + setclkgate("ecspi2.ipg_clk_per", 0); + setclkrate("ecspi2.ipg_clk_per", "osc_25m_ref_clk", 25*Mhz); + setclkgate("ecspi2.ipg_clk_per", 1); + setclkgate("ecspi2.ipg_clk", 1); + + memset(&seg, 0, sizeof(seg)); + seg.attr = SG_PHYSICAL | SG_DEVICE | SG_NOEXEC; + seg.name = "ecspi2"; + seg.pa = VIRTIO + 0x830000 - KZERO; + seg.size = BY2PG; + addphysseg(&seg); +} + void main(void) { @@ -305,6 +329,7 @@ main(void) gpioinit(); lcdinit(); tmuinit(); + lpcspiinit(); userinit(); mpinit(); mmu0clear((uintptr*)L1); diff --git a/sys/src/cmd/reform/pm.c b/sys/src/cmd/reform/pm.c index 6e0f3c161..f9b131e32 100644 --- a/sys/src/cmd/reform/pm.c +++ b/sys/src/cmd/reform/pm.c @@ -9,8 +9,17 @@ enum Mhz = 1000*1000, Pwmsrcclk = 25*Mhz, + Scharge = 0, + Sovervolted, + Scooldown, + Sundervolted, + Smissing, + Sfullycharged, + Spowersave, + Light = 1, Temp, + Battery, PWMSAR = 0x0c/4, PWMPR = 0x10/4, @@ -39,10 +48,32 @@ enum TMUTTR2CR = 0xf18/4, TMUTTR3CR = 0xf1c/4, CR_CAL_PTR_SHIFT = 16, - + + SPIx_RXDATA = 0x00/4, + SPIx_TXDATA = 0x04/4, + SPIx_CONREG = 0x08/4, + CON_BURST_LENGTH = 1<<20, + CON_PRE_DIVIDER = 1<<12, + CON_POST_DIVIDER = 1<<8, + CON_CHAN_MASTER = 1<<4, + CON_XCH = 1<<2, + CON_EN = 1<<0, + SPIx_CONFIGREG = 0x0c/4, + CONFIG_SCLK_CTL_LOW = 0<<20, + CONFIG_DATA_CTL_HIGH = 0<<16, + CONFIG_SS_POL_LOW = 0<<12, + CONFIG_SS_CTL_NCSS = 1<<8, + CONFIG_SCLK_POL_HIGH = 0<<4, + CONFIG_SCLK_PHA_1 = 1<<0, + SPIx_INTREG = 0x10/4, + SPIx_STATREG = 0x18/4, + STAT_TC = 1<<7, + STAT_RR = 1<<3, + STAT_TE = 1<<0, + SPIx_PERIODREG = 0x1c/4, }; -static u32int *pwm2, *tmu; +static u32int *pwm2, *tmu, *spi2; static char *uid = "pm"; static void @@ -148,6 +179,107 @@ tmuinit(void) wr(tmu, TMUTMR, TMR_ME | 3< 0) + state = "discharging"; + }else{ + switch(st[5]){ + case Sfullycharged: state = "full"; break; + case Smissing: state = "missing"; break; + case Sovervolted: state = "overvolted"; break; + case Scooldown: state = "cooldown"; break; + case Spowersave: state = "powersave"; break; + } + } + + if(st[5] != Smissing){ + snprint(buf, sz, "%d mA %d %d %d ? %d mV %d ? ??:??:?? %s\n", + st[4], + ch[0]|ch[1]<<8, ch[4]|ch[5]<<8, ch[4]|ch[5]<<8, ch[2]|ch[3]<<8, + st[0]|st[1]<<8, + state + ); + return 0; + } + + return -1; +} + static void fsread(Req *r) { @@ -163,6 +295,11 @@ fsread(Req *r) snprint(msg, sizeof(msg), "%d.0\n", c[0]); else snprint(msg, sizeof(msg), "%r\n"); + }else if(r->fid->file->aux == (void*)Battery){ + if(readbattery(msg, sizeof(msg)) != 0){ + respond(r, "missing"); + return; + } } } @@ -233,8 +370,11 @@ main(int argc, char **argv) sysfatal("no tmu"); if((pwm2 = segattach(0, "pwm2", 0, 0x18)) == (void*)-1) sysfatal("no pwm2"); + if((spi2 = segattach(0, "ecspi2", 0, 0x20)) == (void*)-1) + sysfatal("no spi2"); tmuinit(); fs.tree = alloctree(uid, uid, DMDIR|0555, nil); + createfile(fs.tree->root, "battery", uid, 0444,(void*)Battery); createfile(fs.tree->root, "cputemp", uid, 0444, (void*)Temp); createfile(fs.tree->root, "light", uid, 0666, (void*)Light); postmountsrv(&fs, srv, mtpt, MAFTER); -- cgit v1.2.3