Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sparc64/dev Extend the monitoring to battery state,...



details:   https://anonhg.NetBSD.org/src/rev/3a82931615a6
branches:  trunk
changeset: 932792:3a82931615a6
user:      jdc <jdc%NetBSD.org@localhost>
date:      Sat May 16 07:16:14 2020 +0000

description:
Extend the monitoring to battery state, with capacity based on voltage.
Add more PMU definitions.

diffstat:

 sys/arch/sparc64/dev/tadpmu.c    |  282 +++++++++++++++++++++++++++++++-------
 sys/arch/sparc64/dev/tadpmureg.h |   63 ++++++-
 sys/arch/sparc64/dev/tadpmuvar.h |   24 ++-
 3 files changed, 301 insertions(+), 68 deletions(-)

diffs (truncated from 553 to 300 lines):

diff -r af10f6bfce56 -r 3a82931615a6 sys/arch/sparc64/dev/tadpmu.c
--- a/sys/arch/sparc64/dev/tadpmu.c     Sat May 16 00:43:15 2020 +0000
+++ b/sys/arch/sparc64/dev/tadpmu.c     Sat May 16 07:16:14 2020 +0000
@@ -1,4 +1,4 @@
-/*/* $NetBSD: tadpmu.c,v 1.4 2018/10/14 05:08:39 macallan Exp $ */
+/*/* $NetBSD: tadpmu.c,v 1.5 2020/05/16 07:16:14 jdc Exp $ */
 
 /*-
  * Copyright (c) 2018 Michael Lorenz <macallan%netbsd.org@localhost>
@@ -26,7 +26,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* a driver for the PMU found in Tadpole Wiper and possibly SPARCle laptops */
+/* a driver for the PMU found in Tadpole Viper and SPARCle laptops */
 
 #include "opt_tadpmu.h"
 #ifdef HAVE_TADPMU
@@ -56,13 +56,16 @@
 static bus_space_tag_t tadpmu_iot;
 static bus_space_handle_t tadpmu_hcmd;
 static bus_space_handle_t tadpmu_hdata;
-static struct sysmon_envsys *tadpmu_sme;
-static envsys_data_t tadpmu_sensors[5];
+static struct sysmon_envsys *tadpmu_sens_sme;
+static struct sysmon_envsys *tadpmu_acad_sme;
+static struct sysmon_envsys *tadpmu_batt_sme;
+static envsys_data_t tadpmu_sensors[8];
 static uint8_t idata = 0xff;
 static uint8_t ivalid = 0;
+static uint8_t ev_data = 0;
 static wchan_t tadpmu, tadpmuev;
-static struct sysmon_pswitch tadpmu_pbutton, tadpmu_lidswitch;
-static kmutex_t tadpmu_lock;
+static struct sysmon_pswitch tadpmu_pbutton, tadpmu_lidswitch, tadpmu_dcpower;
+static kmutex_t tadpmu_lock, data_lock;
 static lwp_t *tadpmu_thread;
 static int tadpmu_dying = 0;
 
@@ -202,10 +205,52 @@
        }
 }
 
+static uint32_t
+tadpmu_battery_capacity(uint8_t gstat)
+{
+       uint8_t res;
+
+       if (gstat == GENSTAT_STATE_BATTERY_FULL) {
+               return ENVSYS_BATTERY_CAPACITY_NORMAL;
+       }
+
+       mutex_enter(&tadpmu_lock);
+       tadpmu_flush();
+       tadpmu_send_cmd(CMD_READ_VBATT);
+       res = tadpmu_recv();
+       mutex_exit(&tadpmu_lock);
+
+       if (gstat & GENSTAT_STATE_BATTERY_DISCHARGE) {
+               if (res < TADPMU_BATT_DIS_CAP_CRIT)
+                       return ENVSYS_BATTERY_CAPACITY_CRITICAL;
+               if (res < TADPMU_BATT_DIS_CAP_WARN)
+                       return ENVSYS_BATTERY_CAPACITY_WARNING;
+               if (res < TADPMU_BATT_DIS_CAP_LOW)
+                       return ENVSYS_BATTERY_CAPACITY_LOW;
+               else
+                       return ENVSYS_BATTERY_CAPACITY_NORMAL;
+       } else if (gstat == GENSTAT_STATE_BATTERY_CHARGE) {
+               if (res < TADPMU_BATT_CHG_CAP_CRIT)
+                       return ENVSYS_BATTERY_CAPACITY_CRITICAL;
+               else if (res < TADPMU_BATT_CHG_CAP_WARN)
+                       return ENVSYS_BATTERY_CAPACITY_WARNING;
+               else if (res < TADPMU_BATT_CHG_CAP_LOW)
+                       return ENVSYS_BATTERY_CAPACITY_LOW;
+               else
+                       return ENVSYS_BATTERY_CAPACITY_NORMAL;
+       } else {
+               DPRINTF("%s unknown battery state %02x\n",
+                   __func__, gstat);
+               return ENVSYS_BATTERY_CAPACITY_NORMAL;
+       }
+}
+
+/* The data to read is calculated from the command and the units */
 static void
 tadpmu_sensors_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
 {
        int res;
+
        if (edata->private > 0) {
                mutex_enter(&tadpmu_lock);
                tadpmu_flush();
@@ -214,8 +259,27 @@
                mutex_exit(&tadpmu_lock);
                if (edata->units == ENVSYS_STEMP) {
                        edata->value_cur = res * 1000000 + 273150000;
+               } else if (edata->units == ENVSYS_SVOLTS_DC) {
+                       edata->value_cur = res * 100000;
+               } else if (edata->units == ENVSYS_BATTERY_CHARGE) {
+                       if (res & GENSTAT_BATTERY_CHARGING)
+                               edata->value_cur = ENVSYS_INDICATOR_TRUE;
+                       else
+                               edata->value_cur = ENVSYS_INDICATOR_FALSE;
+               } else if (edata->units == ENVSYS_BATTERY_CAPACITY) {
+                       edata->value_cur = tadpmu_battery_capacity(res);
                } else {
-                       edata->value_cur = res;
+                       if (edata->units == ENVSYS_INDICATOR &&
+                           edata->private == CMD_READ_GENSTAT) {
+                               if (res & GENSTAT_DC_PRESENT)
+                                       edata->value_cur =
+                                           ENVSYS_INDICATOR_TRUE;
+                               else
+                                       edata->value_cur =
+                                           ENVSYS_INDICATOR_FALSE;
+                       } else {
+                               edata->value_cur = res;
+                       }
                }
                edata->state = ENVSYS_SVALID;
        } else {
@@ -226,27 +290,73 @@
 static void
 tadpmu_events(void *cookie)
 {
-       uint8_t res, ores = 0;
+       uint8_t events, gs, vb;
+
        while (!tadpmu_dying) {
                mutex_enter(&tadpmu_lock);
                tadpmu_flush();
                tadpmu_send_cmd(CMD_READ_GENSTAT);
-               res = tadpmu_recv();
+               gs = tadpmu_recv();
+               tadpmu_send_cmd(CMD_READ_VBATT);
+               vb = tadpmu_recv();
                mutex_exit(&tadpmu_lock);
-               res &= GENSTAT_LID_CLOSED;
-               if (res != ores) {
-                       ores = res;
+
+               mutex_enter(&data_lock);
+               events = ev_data;
+               mutex_exit(&data_lock);
+               DPRINTF("%s event %02x, status %02x/%02x\n", __func__,
+                   events, gs, vb);
+
+               if (events & TADPMU_EV_PWRBUTT) {
+                       mutex_enter(&data_lock);
+                       ev_data &= ~TADPMU_EV_PWRBUTT;
+                       mutex_exit(&data_lock);
+                       sysmon_pswitch_event(&tadpmu_pbutton,
+                           PSWITCH_EVENT_PRESSED);
+               }
+
+               if (events & TADPMU_EV_LID) {
+                       mutex_enter(&data_lock);
+                       ev_data &= ~TADPMU_EV_LID;
+                       mutex_exit(&data_lock);
                        sysmon_pswitch_event(&tadpmu_lidswitch, 
-                                   (res & GENSTAT_LID_CLOSED) ? 
-                                       PSWITCH_EVENT_PRESSED :
-                                       PSWITCH_EVENT_RELEASED);
+                           gs & GENSTAT_LID_CLOSED ? 
+                           PSWITCH_EVENT_PRESSED : PSWITCH_EVENT_RELEASED);
+               }
+
+               if (events & TADPMU_EV_DCPOWER) {
+                       mutex_enter(&data_lock);
+                       ev_data &= ~TADPMU_EV_DCPOWER;
+                       mutex_exit(&data_lock);
+                       sysmon_pswitch_event(&tadpmu_dcpower, 
+                           gs & GENSTAT_DC_PRESENT ? 
+                           PSWITCH_EVENT_PRESSED : PSWITCH_EVENT_RELEASED);
                }
+
+               if (events & TADPMU_EV_BATTCHANGE) {
+                       mutex_enter(&data_lock);
+                       ev_data &= ~TADPMU_EV_BATTCHANGE;
+                       mutex_exit(&data_lock);
+                       if (gs == GENSTAT_STATE_BATTERY_DISCHARGE) {
+                               if (vb < TADPMU_BATT_DIS_CAP_CRIT)
+                                       printf("Battery critical!\n");
+                               else if (vb < TADPMU_BATT_DIS_CAP_WARN)
+                                       printf("Battery warning!\n");
+                       }
+               }
+
+               if (events & TADPMU_EV_BATTCHARGED) {
+                       mutex_enter(&data_lock);
+                       ev_data &= ~TADPMU_EV_BATTCHARGED;
+                       mutex_exit(&data_lock);
+                       printf("Battery charged\n");
+               }
+
                tsleep(tadpmuev, 0, "tadpmuev", hz);            
        }
        kthread_exit(0);
 }
 
-
 int
 tadpmu_intr(void *cookie)
 {
@@ -254,17 +364,38 @@
        if (s & STATUS_INTR) {
                /* interrupt message */
                d = tadpmu_data();
-               DPRINTF("status change %02x\n", d);
+               DPRINTF("%s status change %02x\n", __func__, d);
+
                switch (d) {
-                       case TADPMU_POWERBUTTON:
-                               sysmon_pswitch_event(&tadpmu_pbutton, 
-                                   PSWITCH_EVENT_PRESSED);
+                       case TADPMU_INTR_POWERBUTTON:
+                               mutex_enter(&data_lock);
+                               ev_data |= TADPMU_EV_PWRBUTT;;
+                               mutex_exit(&data_lock);
+                               break;
+                       case TADPMU_INTR_LID:
+                               mutex_enter(&data_lock);
+                               ev_data |= TADPMU_EV_LID;
+                               mutex_exit(&data_lock);
                                break;
-                       case TADPMU_LID:
-                               /* read genstat and report lid */
-                               wakeup(tadpmuev);
+                       case TADPMU_INTR_DCPOWER:
+                               mutex_enter(&data_lock);
+                               ev_data |= TADPMU_EV_DCPOWER;
+                               mutex_exit(&data_lock);
+                               break;
+                       case TADPMU_INTR_BATTERY_STATE:
+                               mutex_enter(&data_lock);
+                               ev_data |= TADPMU_EV_BATTCHANGE;
+                               mutex_exit(&data_lock);
+                               break;
+                       case TADPMU_INTR_BATTERY_CHARGED:
+                               mutex_enter(&data_lock);
+                               ev_data |= TADPMU_EV_BATTCHARGED;
+                               mutex_exit(&data_lock);
                                break;
                }
+               /* Report events */
+               if (ev_data)
+                       wakeup(tadpmuev);
        }
        s = tadpmu_status();
        if (s & STATUS_HAVE_DATA) {
@@ -280,7 +411,7 @@
 int 
 tadpmu_init(bus_space_tag_t t, bus_space_handle_t hcmd, bus_space_handle_t hdata)
 {
-       int ver;
+       uint8_t ver;
 
        tadpmu_iot = t;
        tadpmu_hcmd = hcmd;
@@ -294,52 +425,91 @@
        printf("Tadpole PMU Version 1.%d\n", ver);      
 
        tadpmu_send_cmd(CMD_SET_OPMODE);
-       tadpmu_send(0x75);
+       tadpmu_send(OPMODE_UNIX);
 
+#ifdef TADPMU_DEBUG
        tadpmu_send_cmd(CMD_READ_SYSTEMP);
        ver = tadpmu_recv();
-       printf("Temperature %d\n", ver);        
+       printf("Temperature 0x%02x\n", ver);    
 
        tadpmu_send_cmd(CMD_READ_VBATT);
        ver = tadpmu_recv();
-       printf("Battery voltage %d\n", ver);    
+       printf("Battery voltage 0x%02x\n", ver);        
 
        tadpmu_send_cmd(CMD_READ_GENSTAT);
        ver = tadpmu_recv();
-       printf("status %02x\n", ver);
+       printf("status 0x%02x\n", ver);
+#endif
 
        mutex_init(&tadpmu_lock, MUTEX_DEFAULT, IPL_NONE);
+       mutex_init(&data_lock, MUTEX_DEFAULT, IPL_HIGH);
 
-       tadpmu_sme = sysmon_envsys_create();
-       tadpmu_sme->sme_name = "tadpmu";
-       tadpmu_sme->sme_cookie = NULL;
-       tadpmu_sme->sme_refresh = tadpmu_sensors_refresh;
+       tadpmu_sens_sme = sysmon_envsys_create();
+       tadpmu_sens_sme->sme_name = "tadpmu";
+       tadpmu_sens_sme->sme_cookie = NULL;
+       tadpmu_sens_sme->sme_refresh = tadpmu_sensors_refresh;
 
+       tadpmu_acad_sme = sysmon_envsys_create();
+       tadpmu_acad_sme->sme_name = "ac adapter";
+       tadpmu_acad_sme->sme_cookie = NULL;
+       tadpmu_acad_sme->sme_refresh = tadpmu_sensors_refresh;
+       tadpmu_acad_sme->sme_class = SME_CLASS_ACADAPTER;



Home | Main Index | Thread Index | Old Index