raster pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=1d87379d47945fa25bbc6247f1ee2a37b534c0b5

commit 1d87379d47945fa25bbc6247f1ee2a37b534c0b5
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
Date:   Fri Sep 11 00:00:38 2020 +0100

    temp - move entirely to hwmon based temp sensors on linux
---
 src/modules/temperature/e_mod_config.c  |  197 +----
 src/modules/temperature/e_mod_main.c    |   14 +-
 src/modules/temperature/e_mod_main.h    |   29 +-
 src/modules/temperature/e_mod_tempget.c | 1225 +++++++++++++++++++------------
 4 files changed, 822 insertions(+), 643 deletions(-)

diff --git a/src/modules/temperature/e_mod_config.c 
b/src/modules/temperature/e_mod_config.c
index b83d7adaa..9e069ed14 100644
--- a/src/modules/temperature/e_mod_config.c
+++ b/src/modules/temperature/e_mod_config.c
@@ -6,16 +6,14 @@
 
 struct _E_Config_Dialog_Data
 {
-   struct
-     {
-        int interval;
-     } poll;
+   struct {
+      int interval;
+   } poll;
 
    int unit_method;
-   struct
-     {
-        int low, high;
-     } temp;
+   struct {
+      int low, high;
+   } temp;
 
    int sensor;
    Eina_List *sensors;
@@ -28,56 +26,11 @@ struct _E_Config_Dialog_Data
 /* local function prototypes */
 static void *_create_data(E_Config_Dialog *cfd);
 static void _fill_data_tempget(E_Config_Dialog_Data *cfdata);
-static void _fill_sensors(E_Config_Dialog_Data *cfdata, const char *name);
 static void _free_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data 
*cfdata);
 static Evas_Object *_basic_create(E_Config_Dialog *cfd, Evas *evas, 
E_Config_Dialog_Data *cfdata);
 static int _basic_apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
 static void _cb_display_changed(void *data, Evas_Object *obj EINA_UNUSED);
 
-static Eina_List *
-temperature_get_bus_files(const char *bus)
-{
-   Eina_List *result;
-   Eina_List *therms;
-   char path[PATH_MAX +  PATH_MAX + 3];
-   char busdir[PATH_MAX];
-   char *name;
-
-   result = NULL;
-
-   snprintf(busdir, sizeof(busdir), "/sys/bus/%s/devices", bus);
-   /* Look through all the devices for the given bus. */
-   therms = ecore_file_ls(busdir);
-
-   EINA_LIST_FREE(therms, name)
-     {
-        Eina_List *files;
-        char *file;
-
-        /* Search each device for temp*_input, these should be
-         * temperature devices. */
-        snprintf(path, sizeof(path), "%s/%s", busdir, name);
-        files = ecore_file_ls(path);
-        EINA_LIST_FREE(files, file)
-          {
-             if ((!strncmp("temp", file, 4)) &&
-                 (!strcmp("_input", &file[strlen(file) - 6])))
-               {
-                  char *f;
-
-                  snprintf(path, sizeof(path),
-                           "%s/%s/%s", busdir, name, file);
-                  f = strdup(path);
-                  if (f) result = eina_list_append(result, f);
-               }
-             free(file);
-          }
-        free(name);
-     }
-   return result;
-}
-
-
 void
 config_temperature_module(Config_Face *inst)
 {
@@ -118,119 +71,38 @@ _fill_data_tempget(E_Config_Dialog_Data *cfdata)
    cfdata->temp.low = cfdata->inst->low;
    cfdata->temp.high = cfdata->inst->high;
    cfdata->sensor = 0;
-   switch (cfdata->inst->sensor_type)
-     {
-      case SENSOR_TYPE_NONE:
-      case SENSOR_TYPE_FREEBSD:
-      case SENSOR_TYPE_OMNIBOOK:
-      case SENSOR_TYPE_LINUX_MACMINI:
-      case SENSOR_TYPE_LINUX_PBOOK:
-      case SENSOR_TYPE_LINUX_INTELCORETEMP:
-        break;
-      case SENSOR_TYPE_LINUX_I2C:
-        _fill_sensors(cfdata, "i2c");
-        break;
-      case SENSOR_TYPE_LINUX_PCI:
-        _fill_sensors(cfdata, "pci");
-        break;
-      case SENSOR_TYPE_LINUX_ACPI:
-          {
-             Eina_List *l;
-
-             if ((l = ecore_file_ls("/proc/acpi/thermal_zone")))
-               {
-                  char *name;
-                  int n = 0;
-
-                  EINA_LIST_FREE(l, name)
-                    {
-                       cfdata->sensors =
-                         eina_list_append(cfdata->sensors, name);
-                       if (cfdata->inst->sensor_name)
-                         {
-                            if (!strcmp(cfdata->inst->sensor_name, name))
-                              cfdata->sensor = n;
-                         }
-                       n++;
-                    }
-               }
-             break;
-          }
-      case SENSOR_TYPE_LINUX_SYS:
-          {
-             Eina_List *l;
-
-             if ((l = ecore_file_ls("/sys/class/thermal")))
-               {
-                  char *name;
-                  int n = 0;
-
-                  EINA_LIST_FREE(l, name)
-                    {
-                       if (!strncmp(name, "thermal", 7))
-                         {
-                            cfdata->sensors =
-                              eina_list_append(cfdata->sensors, name);
-                            if (cfdata->inst->sensor_name)
-                              {
-                                 if (!strcmp(cfdata->inst->sensor_name, name))
-                                   cfdata->sensor = n;
-                              }
-                            n++;
-                         }
-                    }
-               }
-             break;
-          }
-      default:
-        break;
-     }
-}
-
-static void
-_fill_sensors(E_Config_Dialog_Data *cfdata, const char *name)
-{
-   Eina_List *therms, *l;
-   char *n;
+#if defined (__FreeBSD__) || defined(__DragonFly__)
+#elif defined(__OpenBSD__)
+#else
+   Eina_List *sensors;
+   Sensor *sen;
+   int n;
 
-   if (!name) return;
-   if ((therms = temperature_get_bus_files(name)))
+   sensors = temperature_tempget_sensor_list();
+   n = 0;
+   EINA_LIST_FREE(sensors, sen)
      {
-        char path[PATH_MAX];
-
-        EINA_LIST_FREE(therms, n)
-          {
-             if (ecore_file_exists(n))
-               {
-                  int len;
-
-                  sprintf(path, "%s", ecore_file_file_get(n));
-                  len = strlen(path);
-                  if (len > 6) path[len - 6] = '\0';
-                  cfdata->sensors =
-                    eina_list_append(cfdata->sensors, strdup(path));
-               }
-             free(n);
-          }
-     }
-   EINA_LIST_FOREACH(cfdata->sensors, l, n)
-     {
-        if (cfdata->inst->sensor_name)
-          {
-             if (!strcmp(cfdata->inst->sensor_name, n)) break;
-          }
-        cfdata->sensor++;
+        if ((cfdata->inst->sensor_name) &&
+            (!strcmp(sen->name, cfdata->inst->sensor_name)))
+          cfdata->sensor = n;
+        cfdata->sensors = eina_list_append(cfdata->sensors, sen);
+        n++;
      }
+#endif
 }
 
 static void
 _free_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
 {
-   char *sensor;
+   Sensor *sen;
 
    cfdata->inst->config_dialog = NULL;
-   EINA_LIST_FREE(cfdata->sensors, sensor)
-     free(sensor);
+   EINA_LIST_FREE(cfdata->sensors, sen)
+     {
+        eina_stringshare_replace(&(sen->name), NULL);
+        eina_stringshare_replace(&(sen->label), NULL);
+        free(sen);
+     }
    E_FREE(cfdata);
 }
 
@@ -246,15 +118,15 @@ _basic_create(E_Config_Dialog *cfd EINA_UNUSED, Evas 
*evas, E_Config_Dialog_Data
 
    if (cfdata->sensors)
      {
+        Sensor *sen;
         Eina_List *l;
-        char *name;
         int n = 0;
 
         ol = e_widget_list_add(evas, 0, 0);
         rg = e_widget_radio_group_new(&(cfdata->sensor));
-        EINA_LIST_FOREACH(cfdata->sensors, l, name)
+        EINA_LIST_FOREACH(cfdata->sensors, l, sen)
           {
-             ow = e_widget_radio_add(evas, _(name), n, rg);
+             ow = e_widget_radio_add(evas, sen->label, n, rg);
              e_widget_list_object_append(ol, ow, 1, 0, 0.5);
              n++;
           }
@@ -314,13 +186,16 @@ _basic_create(E_Config_Dialog *cfd EINA_UNUSED, Evas 
*evas, E_Config_Dialog_Data
 static int
 _basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
 {
+   Sensor *sen;
+
    cfdata->inst->poll_interval = cfdata->poll.interval;
    cfdata->inst->units = cfdata->unit_method;
    cfdata->inst->low = cfdata->temp.low;
    cfdata->inst->high = cfdata->temp.high;
 
-   eina_stringshare_replace(&cfdata->inst->sensor_name,
-                            eina_list_nth(cfdata->sensors, cfdata->sensor));
+   sen = eina_list_nth(cfdata->sensors, cfdata->sensor);
+   if (sen)
+     eina_stringshare_replace(&(cfdata->inst->sensor_name), sen->name);
 
    e_config_save_queue();
    temperature_face_update_config(cfdata->inst);
diff --git a/src/modules/temperature/e_mod_main.c 
b/src/modules/temperature/e_mod_main.c
index 765fc9fdf..0f24e1c37 100644
--- a/src/modules/temperature/e_mod_main.c
+++ b/src/modules/temperature/e_mod_main.c
@@ -51,7 +51,6 @@ static void
 _temperature_thread_free(Tempthread *tth)
 {
    eina_stringshare_del(tth->sensor_name);
-   eina_stringshare_del(tth->sensor_path);
    e_powersave_sleeper_free(tth->sleeper);
    free(tth->extn);
    free(tth);
@@ -123,7 +122,6 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, 
const char *style)
         inst->poll_interval = 128;
         inst->low = 30;
         inst->high = 80;
-        inst->sensor_type = SENSOR_TYPE_LINUX_SYS;
         inst->sensor_name = NULL;
         inst->temp = -900;
         inst->units = CELSIUS;
@@ -207,7 +205,6 @@ _gc_id_new(const E_Gadcon_Client_Class *client_class 
EINA_UNUSED)
    inst->poll_interval = 128;
    inst->low = 30;
    inst->high = 80;
-   inst->sensor_type = SENSOR_TYPE_LINUX_SYS;
    inst->sensor_name = NULL;
    inst->units = CELSIUS;
    if (!temperature_config->faces)
@@ -282,11 +279,6 @@ _temperature_face_id_max(const Eina_Hash *hash 
EINA_UNUSED, const void *key, voi
    p = strrchr(key, '.');
    if (p) num = atoi(p + 1);
    if (num > *max) *max = num;
-#if defined (__FreeBSD__) || defined(__DragonFly__) || defined (__OpenBSD__)
-   cf->sensor_type = SENSOR_TYPE_FREEBSD;
-#else
-   cf->sensor_type = SENSOR_TYPE_LINUX_SYS;
-#endif
    return EINA_TRUE;
 }
 
@@ -302,8 +294,8 @@ _temperature_check_main(void *data, Ecore_Thread *th)
         temp = temperature_tempget_get(tth);
         if (ptemp != temp) ecore_thread_feedback(th, (void *)((long)temp));
         ptemp = temp;
-        e_powersave_sleeper_sleep(tth->sleeper, tth->poll_interval);
         if (ecore_thread_check(th)) break;
+        e_powersave_sleeper_sleep(tth->sleeper, tth->poll_interval);
      }
 }
 
@@ -333,7 +325,6 @@ temperature_face_update_config(Config_Face *inst)
 
    tth = calloc(1, sizeof(Tempthread));
    tth->poll_interval = inst->poll_interval;
-   tth->sensor_type = inst->sensor_type;
    tth->inst = inst;
    tth->sleeper = e_powersave_sleeper_new();
    if (inst->sensor_name)
@@ -365,7 +356,6 @@ e_modapi_init(E_Module *m)
    E_CONFIG_VAL(D, T, poll_interval, INT);
    E_CONFIG_VAL(D, T, low, INT);
    E_CONFIG_VAL(D, T, high, INT);
-   E_CONFIG_VAL(D, T, sensor_type, INT);
    E_CONFIG_VAL(D, T, sensor_name, STR);
    E_CONFIG_VAL(D, T, units, INT);
 
@@ -383,6 +373,7 @@ e_modapi_init(E_Module *m)
      eina_hash_foreach(temperature_config->faces, _temperature_face_id_max, 
&uuid);
    temperature_config->module = m;
 
+   temperature_tempget_setup();
    e_gadcon_provider_register(&_gadcon_class);
    return m;
 }
@@ -394,6 +385,7 @@ e_modapi_shutdown(E_Module *m EINA_UNUSED)
    if (temperature_config->faces)
      eina_hash_foreach(temperature_config->faces, _temperature_face_shutdown, 
NULL);
    eina_hash_free(temperature_config->faces);
+   temperature_tempget_clear();
    free(temperature_config);
    temperature_config = NULL;
    E_CONFIG_DD_FREE(conf_face_edd);
diff --git a/src/modules/temperature/e_mod_main.h 
b/src/modules/temperature/e_mod_main.h
index 4eb557957..33e902085 100644
--- a/src/modules/temperature/e_mod_main.h
+++ b/src/modules/temperature/e_mod_main.h
@@ -3,22 +3,6 @@
 
 #include "e.h"
 
-typedef enum _Sensor_Type
-{
-   SENSOR_TYPE_NONE,
-   SENSOR_TYPE_FREEBSD,
-   SENSOR_TYPE_OPENBSD,
-   SENSOR_TYPE_OMNIBOOK,
-   SENSOR_TYPE_LINUX_MACMINI,
-   SENSOR_TYPE_LINUX_I2C,
-   SENSOR_TYPE_LINUX_ACPI,
-   SENSOR_TYPE_LINUX_PCI,
-   SENSOR_TYPE_LINUX_PBOOK,
-   SENSOR_TYPE_LINUX_INTELCORETEMP,
-   SENSOR_TYPE_LINUX_THINKPAD,
-   SENSOR_TYPE_LINUX_SYS
-} Sensor_Type;
-
 typedef struct _Config Config;
 typedef struct _Config_Face Config_Face;
 typedef struct _Tempthread Tempthread;
@@ -33,9 +17,7 @@ struct _Tempthread
 {
    Config_Face *inst;
    int poll_interval;
-   Sensor_Type sensor_type;
    const char *sensor_name;
-   const char *sensor_path;
    void *extn;
    E_Powersave_Sleeper *sleeper;
    Eina_Bool initted E_BITFIELD;
@@ -80,7 +62,16 @@ E_API int e_modapi_save(E_Module *m);
 void config_temperature_module(Config_Face *inst);
 void temperature_face_update_config(Config_Face *inst);
 
-int temperature_tempget_get(Tempthread *tth);
+typedef struct
+{
+   const char *name;
+   const char *label;
+} Sensor;
+
+int        temperature_tempget_get(Tempthread *tth);
+Eina_List *temperature_tempget_sensor_list(void);
+void       temperature_tempget_setup(void);
+void       temperature_tempget_clear(void);
 
 /**
  * @addtogroup Optional_Gadgets
diff --git a/src/modules/temperature/e_mod_tempget.c 
b/src/modules/temperature/e_mod_tempget.c
index 50166f9dd..5d151999c 100644
--- a/src/modules/temperature/e_mod_tempget.c
+++ b/src/modules/temperature/e_mod_tempget.c
@@ -5,82 +5,615 @@
 # include <sys/types.h>
 # include <sys/sysctl.h>
 # include <errno.h>
-#endif
-
-#ifdef __OpenBSD__
+#elif defined (__OpenBSD__)
 # include <sys/param.h>
 # include <sys/sysctl.h>
 # include <sys/sensors.h>
 # include <errno.h>
 # include <err.h>
-#endif
+#else
+// https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
+typedef enum
+{
+   TEMP_UNKNOWN,
+   TEMP_CPU, // CPU embedded diode
+   TEMP_TRANSISTOR, // 3904 transistor
+   TEMP_THERMAL, // thermal diode
+   TEMP_THERMISTOR, // thermistor
+   TEMP_AMD_AMDSI, // AMD AMDSI
+   TEMP_INTEL_PECI // Intel PECI
+} Temp_Type;
+
+typedef enum
+{
+   PWM_OFF, // full speed
+   PWM_ON, // enabled
+   PWM_AUTO // automatic mode
+} Pwm_Mode;
 
 typedef struct
 {
-#if defined (__FreeBSD__) || defined(__DragonFly__) || defined (__OpenBSD__)
-   int mib[CTL_MAXNAME];
-#endif
-#if defined (__FreeBSD__) || defined(__DragonFly__)
-   unsigned int miblen;
-#endif
-   int dummy;
-} Extn;
+   Temp_Type type;
+   const char *path;
+   const char *name;
+   const char *label;
+   int enable;
+   int fault;
+   double temp;
+   double min;
+   double max;
+   double crit;
+   double emergency;
+   double offset;
+} Temp;
 
-#if defined (__FreeBSD__) || defined(__DragonFly__)
-static const char *sources[] =
-  {
-     "hw.acpi.thermal.tz0.temperature",
-     "dev.cpu.0.temperature",
-     "dev.aibs.0.temp.0",
-     "dev.lm75.0.temperature",
-     NULL
-  };
-#endif
+typedef struct
+{
+   const char *path;
+   const char *name;
+   const char *label;
+   int enable;
+   int fault;
+   int rpm;
+   int min;
+   int max;
+   int target;
+} Fan;
 
-Eina_List *
-temperature_get_bus_files(const char *bus)
+typedef struct
+{
+   const char *path;
+   const char *name;
+   Pwm_Mode mode;
+   double val;
+   double min;
+   double max;
+} Pwm;
+
+typedef struct
+{
+   const char *path;
+   const char *name;
+   const char *label;
+   double mhz;
+} Freq;
+
+typedef struct
+{
+   const char *path;
+   const char *name;
+   int enable;
+   double watts;
+   double min;
+   double max;
+   double cap;
+   double cap_min;
+   double cap_max;
+   double crit;
+} Power;
+
+typedef struct
 {
-   Eina_List *result;
-   Eina_List *therms;
-   char path[PATH_MAX + PATH_MAX + 2];
-   char busdir[PATH_MAX];
-   char *name;
+   const char *path;
+   const char *name;
+   const char *label;
+   int enable;
+   double volts;
+   double min;
+   double max;
+   double crit_min;
+   double crit;
+} Volt;
 
-   result = NULL;
+typedef struct
+{
+   const char *path;
+   const char *name;
+   int enable;
+   double amps;
+   double min;
+   double max;
+   double crit_min;
+   double crit;
+} Amp;
 
-   snprintf(busdir, sizeof(busdir), "/sys/bus/%s/devices", bus);
-   /* Look through all the devices for the given bus. */
-   therms = ecore_file_ls(busdir);
+typedef struct
+{
+   const char *path;
+   const char *name;
+   int enable;
+   double joules;
+} Energy;
+
+typedef struct
+{
+   const char *path;
+   const char *name;
+   int enable;
+   double percent;
+} Humid;
 
-   EINA_LIST_FREE(therms, name)
+typedef struct
+{
+   const char *path;
+   const char *name;
+   int alarm;
+} Intrusion;
+
+typedef struct
+{
+   const char *path;
+   const char *name;
+   const char *label;
+   Eina_List *temps;
+   Eina_List *fans;
+   Eina_List *pwms;
+   Eina_List *freqs;
+   Eina_List *powers;
+   Eina_List *volts;
+   Eina_List *amps;
+   Eina_List *energies;
+   Eina_List *humids;
+   Eina_List *intrusions;
+} Mon;
+
+static Eina_Lock mons_lock;
+static Eina_List *mons = NULL;
+
+static char *
+_file_str_get(const char *path)
+{
+   int fd = open(path, O_RDONLY);
+   char buf[4096], *str = NULL, *s;
+   ssize_t sz;
+
+   if (fd < 0) return NULL;
+   sz = read(fd, buf, sizeof(buf) - 1);
+   if (sz < 1) goto err;
+   buf[sz] = '\0';
+   for (s = buf; s[0] != '\0'; s++)
+     {
+        if ((s[0] == '\n') || (s[0] == '\r'))
+          {
+             s[0] = '\0';
+             break;
+          }
+     }
+   str = strdup(buf);
+err:
+   close(fd);
+   return str;
+}
+
+#define NOVAL -999999999
+
+static int
+_file_int_get(const char *path)
+{
+   char *str = _file_str_get(path);
+   if (!str) return NOVAL;
+   int val = atoi(str);
+   free(str);
+   return val;
+}
+
+#define GETVAL_STR(_base, _name, _field) do { char *_s; char _b[1024 + 512]; \
+   snprintf(_b, sizeof(_b), "%s_%s", _base, _name); \
+   if ((_s = _file_str_get(_b))) { \
+      _field = eina_stringshare_add(_s); \
+      free(_s); \
+   } \
+} while (0)
+#define GETVAL_INT(_base, _name, _field) do { int _v; char _b[1024 + 512]; \
+   snprintf(_b, sizeof(_b), "%s_%s", _base, _name); \
+   if ((_v = _file_int_get(_b)) >= 0) _field = _v; \
+} while (0)
+#define GETVAL_DBL(_base, _name, _field, _div) do { int _v; char _b[1024 + 
512]; \
+   snprintf(_b, sizeof(_b), "%s_%s", _base, _name); \
+   if ((_v = _file_int_get(_b)) >= 0) _field = (double)_v / (_div); \
+} while (0)
+
+static void
+_hwmon_init(void)
+{
+   Eina_List *list;
+   char *s, *str, buf[1024], buf2[1024 + 256];
+   int i, x;
+
+   eina_lock_take(&mons_lock);
+   list = ecore_file_ls("/sys/class/hwmon");
+   EINA_LIST_FREE(list, s)
      {
-        Eina_List *files;
-        char *file;
-
-        /* Search each device for temp*_input, these should be
-         * temperature devices. */
-        snprintf(path, sizeof(path), "%s/%s", busdir, name);
-        files = ecore_file_ls(path);
-        EINA_LIST_FREE(files, file)
+        Mon *mon = calloc(1, sizeof(Mon));
+        if (mon)
           {
-             if ((!strncmp("temp", file, 4)) &&
-                 (!strcmp("_input", &file[strlen(file) - 6])))
+             snprintf(buf, sizeof(buf), "/sys/class/hwmon/%s", s);
+             mon->path = eina_stringshare_add(buf);
+             mon->name = eina_stringshare_add(s);
+             snprintf(buf, sizeof(buf), "/sys/class/hwmon/%s/name", s);
+             str = _file_str_get(buf);
+             if (str)
+               {
+                  mon->label = eina_stringshare_add(str);
+                  free(str);
+               }
+             for (i = 1; ; i++)
+               {
+                  snprintf(buf,  sizeof(buf),  "/sys/class/hwmon/%s/temp%i", 
s, i);
+                  snprintf(buf2, sizeof(buf2), "%s_%s", buf, "input");
+                  x = _file_int_get(buf2);
+                  if (x == NOVAL) break;
+                  Temp *t = calloc(1, sizeof(Temp));
+                  if (t)
+                    {
+                       t->temp = (double)x / 1000.0;
+                       t->path = eina_stringshare_add(buf);
+                       snprintf(buf2,  sizeof(buf2),  "temp%i", i);
+                       t->name = eina_stringshare_add(buf2);
+                       GETVAL_STR(buf, "label", t->label);
+                       t->enable = 1;
+                       GETVAL_INT(buf, "enable", t->enable);
+                       GETVAL_INT(buf, "fault", t->fault);
+                       GETVAL_INT(buf, "type", t->type);
+                       GETVAL_DBL(buf, "min", t->min, 1000.0);
+                       GETVAL_DBL(buf, "max", t->max, 1000.0);
+                       GETVAL_DBL(buf, "crit", t->crit, 1000.0);
+                       GETVAL_DBL(buf, "emergency", t->emergency, 1000.0);
+                       mon->temps = eina_list_append(mon->temps, t);
+                    }
+               }
+             for (i = 1; ; i++)
+               {
+                  snprintf(buf,  sizeof(buf),  "/sys/class/hwmon/%s/fan%i", s, 
i);
+                  snprintf(buf2, sizeof(buf2), "%s_%s", buf, "input");
+                  x = _file_int_get(buf2);
+                  if (x == NOVAL) break;
+                  Fan *f = calloc(1, sizeof(Fan));
+                  if (f)
+                    {
+                       f->rpm = x;
+                       f->path = eina_stringshare_add(buf);
+                       snprintf(buf2,  sizeof(buf2),  "fan%i", i);
+                       f->name = eina_stringshare_add(buf2);
+                       GETVAL_STR(buf, "label", f->label);
+                       f->enable = 1;
+                       GETVAL_INT(buf, "enable", f->enable);
+                       GETVAL_INT(buf, "fault", f->fault);
+                       GETVAL_INT(buf, "min", f->min);
+                       GETVAL_INT(buf, "max", f->max);
+                       GETVAL_INT(buf, "target", f->target);
+                       mon->fans = eina_list_append(mon->fans, f);
+                    }
+               }
+             for (i = 1; ; i++)
+               {
+                  snprintf(buf,  sizeof(buf),  "/sys/class/hwmon/%s/pwm%i", s, 
i);
+                  x = _file_int_get(buf);
+                  if (x == NOVAL) break;
+                  Pwm *p = calloc(1, sizeof(Pwm));
+                  if (p)
+                    {
+                       p->val = (double)x / 255.0;
+                       p->path = eina_stringshare_add(buf);
+                       snprintf(buf2,  sizeof(buf2),  "pwm%i", i);
+                       p->name = eina_stringshare_add(buf2);
+                       GETVAL_INT(buf, "enable", p->mode);
+                       GETVAL_DBL(buf, "min", p->min, 255.0);
+                       GETVAL_DBL(buf, "max", p->max, 255.0);
+                       mon->pwms = eina_list_append(mon->pwms, p);
+                    }
+               }
+             for (i = 1; ; i++)
                {
-                  char *f;
+                  snprintf(buf,  sizeof(buf),  "/sys/class/hwmon/%s/freq%i", 
s, i);
+                  snprintf(buf2, sizeof(buf2), "%s_%s", buf, "input");
+                  x = _file_int_get(buf2);
+                  if (x == NOVAL) break;
+                  Freq *f = calloc(1, sizeof(Freq));
+                  if (f)
+                    {
+                       f->mhz = (double)x / 1000000.0;
+                       f->path = eina_stringshare_add(buf);
+                       snprintf(buf2,  sizeof(buf2),  "freq%i", i);
+                       f->name = eina_stringshare_add(buf2);
+                       GETVAL_STR(buf, "label", f->label);
+                       mon->freqs = eina_list_append(mon->freqs, f);
+                    }
+               }
+             for (i = 1; ; i++)
+               {
+                  snprintf(buf,  sizeof(buf),  "/sys/class/hwmon/%s/power%i", 
s, i);
+                  snprintf(buf2, sizeof(buf2), "%s_%s", buf, "input");
+                  x = _file_int_get(buf2);
+                  if (x < 0)
+                    {
+                       snprintf(buf2, sizeof(buf2), "%s_%s", buf, "average");
+                       x = _file_int_get(buf2);
+                    }
+                  if (x == NOVAL) break;
+                  Power *p = calloc(1, sizeof(Power));
+                  if (p)
+                    {
+                       p->watts = (double)x / 1000000.0;
+                       p->path = eina_stringshare_add(buf);
+                       snprintf(buf2,  sizeof(buf2),  "power%i", i);
+                       p->name = eina_stringshare_add(buf2);
+                       p->enable = 1;
+                       GETVAL_INT(buf, "enable", p->enable);
+                       GETVAL_DBL(buf, "min", p->min, 1000000.0);
+                       GETVAL_DBL(buf, "max", p->max, 1000000.0);
+                       if (p->min <= 0.0)
+                         GETVAL_DBL(buf, "average_min", p->min, 1000000.0);
+                       if (p->max <= 0.0)
+                         GETVAL_DBL(buf, "average_max", p->max, 1000000.0);
+                       GETVAL_DBL(buf, "cap", p->cap, 1000000.0);
+                       GETVAL_DBL(buf, "cap_min", p->cap_min, 1000000.0);
+                       GETVAL_DBL(buf, "cap_max", p->cap_max, 1000000.0);
+                       GETVAL_DBL(buf, "crit", p->crit, 1000000.0);
+                       mon->powers = eina_list_append(mon->powers, p);
+                    }
+               }
+             for (i = 0; ; i++)
+               {
+                  snprintf(buf,  sizeof(buf),  "/sys/class/hwmon/%s/in%i", s, 
i);
+                  snprintf(buf2, sizeof(buf2), "%s_%s", buf, "input");
+                  x = _file_int_get(buf2);
+                  if (x < 0)
+                    {
+                       snprintf(buf2, sizeof(buf2), "%s_%s", buf, "average");
+                       x = _file_int_get(buf2);
+                    }
+                  if (x == NOVAL) break;
+                  Volt *v = calloc(1, sizeof(Volt));
+                  if (v)
+                    {
+                       v->volts = (double)x / 1000.0;
+                       v->path = eina_stringshare_add(buf);
+                       snprintf(buf2,  sizeof(buf2),  "in%i", i);
+                       v->name = eina_stringshare_add(buf2);
+                       GETVAL_STR(buf, "label", v->label);
+                       v->enable = 1;
+                       GETVAL_INT(buf, "enable", v->enable);
+                       GETVAL_DBL(buf, "min", v->min, 1000.0);
+                       GETVAL_DBL(buf, "max", v->max, 1000.0);
+                       GETVAL_DBL(buf, "lcrit", v->crit_min, 1000.0);
+                       GETVAL_DBL(buf, "crit", v->crit, 1000.0);
+                       mon->volts = eina_list_append(mon->volts, v);
+                    }
+               }
+             for (i = 1; ; i++)
+               {
+                  snprintf(buf,  sizeof(buf),  "/sys/class/hwmon/%s/curr%i", 
s, i);
+                  snprintf(buf2, sizeof(buf2), "%s_%s", buf, "input");
+                  x = _file_int_get(buf2);
+                  if (x < 0)
+                    {
+                       snprintf(buf2, sizeof(buf2), "%s_%s", buf, "average");
+                       x = _file_int_get(buf2);
+                    }
+                  if (x == NOVAL) break;
+                  Amp *a = calloc(1, sizeof(Amp));
+                  if (a)
+                    {
+                       a->amps = (double)x / 1000.0;
+                       a->path = eina_stringshare_add(buf);
+                       snprintf(buf2,  sizeof(buf2),  "curr%i", i);
+                       a->name = eina_stringshare_add(buf2);
+                       a->enable = 1;
+                       GETVAL_INT(buf, "enable", a->enable);
+                       GETVAL_DBL(buf, "min", a->min, 1000.0);
+                       GETVAL_DBL(buf, "max", a->max, 1000.0);
+                       GETVAL_DBL(buf, "lcrit", a->crit_min, 1000.0);
+                       GETVAL_DBL(buf, "crit", a->crit, 1000.0);
+                       mon->amps = eina_list_append(mon->amps, a);
+                    }
+               }
+             for (i = 1; ; i++)
+               {
+                  snprintf(buf,  sizeof(buf),  "/sys/class/hwmon/%s/energy%i", 
s, i);
+                  snprintf(buf2, sizeof(buf2), "%s_%s", buf, "input");
+                  x = _file_int_get(buf2);
+                  if (x == NOVAL) break;
+                  Energy *e = calloc(1, sizeof(Energy));
+                  if (e)
+                    {
+                       e->joules = (double)x / 1000000.0;
+                       e->path = eina_stringshare_add(buf);
+                       snprintf(buf2,  sizeof(buf2),  "energy%i", i);
+                       e->name = eina_stringshare_add(buf2);
+                       e->enable = 1;
+                       GETVAL_INT(buf, "enable", e->enable);
+                       mon->energies = eina_list_append(mon->energies, e);
+                    }
+               }
+             for (i = 1; ; i++)
+               {
+                  snprintf(buf,  sizeof(buf),  
"/sys/class/hwmon/%s/humidity%i", s, i);
+                  snprintf(buf2, sizeof(buf2), "%s_%s", buf, "input");
+                  x = _file_int_get(buf2);
+                  if (x == NOVAL) break;
+                  Humid *h = calloc(1, sizeof(Humid));
+                  if (h)
+                    {
+                       h->percent = (double)x / 1000.0;
+                       h->path = eina_stringshare_add(buf);
+                       snprintf(buf2,  sizeof(buf2),  "humidity%i", i);
+                       h->name = eina_stringshare_add(buf2);
+                       h->enable = 1;
+                       GETVAL_INT(buf, "enable", h->enable);
+                       mon->humids = eina_list_append(mon->humids, h);
+                    }
+               }
+             for (i = 0; ; i++)
+               {
+                  snprintf(buf,  sizeof(buf),  
"/sys/class/hwmon/%s/intrusion%i", s, i);
+                  snprintf(buf2, sizeof(buf2), "%s_%s", buf, "alarm");
+                  x = _file_int_get(buf2);
+                  if (x == NOVAL) break;
+                  Intrusion *n = calloc(1, sizeof(Intrusion));
+                  if (n)
+                    {
+                       n->alarm = x;
+                       n->path = eina_stringshare_add(buf);
+                       snprintf(buf2,  sizeof(buf2),  "intrusion%i", i);
+                       n->name = eina_stringshare_add(buf2);
+                       mon->intrusions = eina_list_append(mon->intrusions, n);
+                    }
+               }
+             mons = eina_list_append(mons, mon);
+          }
+        free(s);
+     }
+   eina_lock_release(&mons_lock);
+}
 
-                  snprintf(path, sizeof(path),
-                           "%s/%s/%s", busdir, name, file);
-                  f = strdup(path);
-                  if (f) result = eina_list_append(result, f);
+static void
+_hwmon_update(void)
+{
+   Eina_List *l, *ll;
+   Mon *mon;
+   Temp *temp;
+   Fan *fan;
+   Pwm *pwm;
+   Freq *freq;
+   Power *power;
+   Volt *volt;
+   Amp *amp;
+   Energy *energy;
+   Humid *humid;
+   Intrusion *intrusion;
+   int x;
+   char buf[4096];
+
+   eina_lock_take(&mons_lock);
+   EINA_LIST_FOREACH(mons, l, mon)
+     {
+        EINA_LIST_FOREACH(mon->temps, ll, temp)
+          {
+             snprintf(buf, sizeof(buf), "%s_input", temp->path);
+             temp->temp = (double)_file_int_get(buf) / 1000.0;
+             snprintf(buf, sizeof(buf), "%s_enable", temp->path);
+             x = _file_int_get(buf);
+             if (x != NOVAL) temp->enable = x;
+             snprintf(buf, sizeof(buf), "%s_fault", temp->path);
+             temp->fault = _file_int_get(buf);
+          }
+        EINA_LIST_FOREACH(mon->fans, ll, fan)
+          {
+             snprintf(buf, sizeof(buf), "%s_input", fan->path);
+             fan->rpm = _file_int_get(buf);
+             snprintf(buf, sizeof(buf), "%s_target", fan->path);
+             fan->target = _file_int_get(buf);
+             snprintf(buf, sizeof(buf), "%s_enable", fan->path);
+             x = _file_int_get(buf);
+             if (x != NOVAL) fan->enable = x;
+             snprintf(buf, sizeof(buf), "%s_fault", fan->path);
+             fan->fault = _file_int_get(buf);
+          }
+        EINA_LIST_FOREACH(mon->pwms, ll, pwm)
+          {
+             snprintf(buf, sizeof(buf), "%s", pwm->path);
+             pwm->val = (double)_file_int_get(buf) / 255.0;
+             snprintf(buf, sizeof(buf), "%s_enable", pwm->path);
+             x = _file_int_get(buf);
+             if (x != NOVAL) pwm->mode = x;
+          }
+        EINA_LIST_FOREACH(mon->freqs, ll, freq)
+          {
+             snprintf(buf, sizeof(buf), "%s_input", freq->path);
+             freq->mhz = (double)_file_int_get(buf) / 1000000.0;
+          }
+        EINA_LIST_FOREACH(mon->powers, ll, power)
+          {
+             snprintf(buf, sizeof(buf), "%s_input", power->path);
+             x = _file_int_get(buf);
+             if (x == NOVAL)
+               {
+                  snprintf(buf, sizeof(buf), "%s_average", power->path);
+                  x = _file_int_get(buf);
+               }
+             power->watts = (double)x / 1000000.0;
+             snprintf(buf, sizeof(buf), "%s_enable", power->path);
+             x = _file_int_get(buf);
+             if (x != NOVAL) power->enable = x;
+          }
+        EINA_LIST_FOREACH(mon->volts, ll, volt)
+          {
+             snprintf(buf, sizeof(buf), "%s_input", volt->path);
+             x = _file_int_get(buf);
+             if (x == NOVAL)
+               {
+                  snprintf(buf, sizeof(buf), "%s_average", volt->path);
+                  x = _file_int_get(buf);
+               }
+             volt->volts = (double)x / 1000.0;
+             snprintf(buf, sizeof(buf), "%s_enable", volt->path);
+             x = _file_int_get(buf);
+             if (x != NOVAL) volt->enable = x;
+          }
+        EINA_LIST_FOREACH(mon->amps, ll, amp)
+          {
+             snprintf(buf, sizeof(buf), "%s_input", amp->path);
+             x = _file_int_get(buf);
+             if (x == NOVAL)
+               {
+                  snprintf(buf, sizeof(buf), "%s_average", amp->path);
+                  x = _file_int_get(buf);
                }
-             free(file);
+             amp->amps = (double)x / 1000.0;
+             snprintf(buf, sizeof(buf), "%s_enable", amp->path);
+             x = _file_int_get(buf);
+             if (x != NOVAL) amp->enable = x;
+          }
+        EINA_LIST_FOREACH(mon->energies, ll, energy)
+          {
+             snprintf(buf, sizeof(buf), "%s_input", energy->path);
+             energy->joules = (double)_file_int_get(buf) / 1000000.0;
+             snprintf(buf, sizeof(buf), "%s_enable", energy->path);
+             x = _file_int_get(buf);
+             if (x != NOVAL) energy->enable = x;
+         }
+        EINA_LIST_FOREACH(mon->humids, ll, humid)
+          {
+             snprintf(buf, sizeof(buf), "%s_input", humid->path);
+             humid->percent = (double)_file_int_get(buf) / 1000.0;
+             snprintf(buf, sizeof(buf), "%s_enable", humid->path);
+             x = _file_int_get(buf);
+             if (x != NOVAL) humid->enable = x;
+          }
+        EINA_LIST_FOREACH(mon->intrusions, ll, intrusion)
+          {
+             snprintf(buf, sizeof(buf), "%s_alarm", intrusion->path);
+             intrusion->alarm = _file_int_get(buf);
           }
-        free(name);
      }
-   return result;
+   eina_lock_release(&mons_lock);
 }
+#endif
 
-#ifdef __OpenBSD__
+typedef struct
+{
+#if defined (__FreeBSD__) || defined(__DragonFly__) || defined (__OpenBSD__)
+   int mib[CTL_MAXNAME];
+#endif
+#if defined (__FreeBSD__) || defined(__DragonFly__)
+   unsigned int miblen;
+#endif
+   int dummy;
+} Extn;
+
+#if defined (__FreeBSD__) || defined(__DragonFly__)
+static const char *sources[] =
+{
+   "hw.acpi.thermal.tz0.temperature",
+   "dev.cpu.0.temperature",
+   "dev.aibs.0.temp.0",
+   "dev.lm75.0.temperature",
+   NULL
+};
+#endif
+
+#if defined(__OpenBSD__)
 static struct sensor snsr;
 static size_t slen = sizeof(snsr);
 #endif
@@ -88,49 +621,42 @@ static size_t slen = sizeof(snsr);
 static void
 init(Tempthread *tth)
 {
-   Eina_List *therms;
-   char path[512];
-#ifdef __OpenBSD__
-   int dev, numt;
-   struct sensordev snsrdev;
-   size_t sdlen = sizeof(snsrdev);
-#endif
-#if defined (__FreeBSD__) || defined(__DragonFly__)
-   unsigned i;
-   size_t len;
-   int rc;
-#endif
    Extn *extn;
 
    if (tth->initted) return;
    tth->initted = EINA_TRUE;
 
    extn = calloc(1, sizeof(Extn));
-   tth->extn = extn;
+   if (!extn) return;
 
-   if ((!tth->sensor_type) ||
-       ((!tth->sensor_name) ||
-        (tth->sensor_name[0] == 0)))
+   tth->extn = extn;
+   if (((!tth->sensor_name) || (tth->sensor_name[0] == 0)))
      {
-        eina_stringshare_del(tth->sensor_name);
-        tth->sensor_name = NULL;
-        eina_stringshare_del(tth->sensor_path);
-        tth->sensor_path = NULL;
+        eina_stringshare_replace(&(tth->sensor_name), NULL);
 #if defined (__FreeBSD__) || defined(__DragonFly__)
+        unsigned int i;
+        size_t len;
+        int rc;
+
         for (i = 0; sources[i]; i++)
           {
              rc = sysctlbyname(sources[i], NULL, NULL, NULL, 0);
              if (rc == 0)
                {
-                  tth->sensor_type = SENSOR_TYPE_FREEBSD;
                   tth->sensor_name = eina_stringshare_add(sources[i]);
+                  len = sizeof(extn->mib) / sizeof(extn->mib[0]);
+                  rc = sysctlnametomib(tth->sensor_name, extn->mib, &len);
+                  if (rc == 0) extn->miblen = len;
                   break;
                }
           }
 #elif defined(__OpenBSD__)
+        int dev, numt;
+        struct sensordev snsrdev;
+        size_t sdlen = sizeof(snsrdev);
+
         extn->mib[0] = CTL_HW;
         extn->mib[1] = HW_SENSORS;
-
         for (dev = 0;; dev++)
           {
              extn->mib[2] = dev;
@@ -143,437 +669,232 @@ init(Tempthread *tth)
                }
              if (strcmp(snsrdev.xname, "cpu0") == 0)
                {
-                  tth->sensor_type = SENSOR_TYPE_OPENBSD;
-                  tth->sensor_name = strdup("cpu0");
+                  tth->sensor_name = eina_stringshare_add("cpu0");
                   break;
                }
              else if (strcmp(snsrdev.xname, "km0") == 0)
                {
-                  tth->sensor_type = SENSOR_TYPE_OPENBSD;
-                  tth->sensor_name = strdup("km0");
+                  tth->sensor_name = eina_stringshare_add("km0");
                   break;
                }
           }
-#else
-        therms = ecore_file_ls("/proc/acpi/thermal_zone");
-        if (therms)
+        for (numt = 0; numt < snsrdev.maxnumt[SENSOR_TEMP]; numt++)
           {
-             char *name;
-
-             name = eina_list_data_get(therms);
-             tth->sensor_type = SENSOR_TYPE_LINUX_ACPI;
-             tth->sensor_name = eina_stringshare_add(name);
-             EINA_LIST_FREE(therms, name) free(name);
+             extn->mib[4] = numt;
+             slen = sizeof(snsr);
+             if (sysctl(extn->mib, 5, &snsr, &slen, NULL, 0) == -1)
+               continue;
+             if (slen > 0 && (snsr.flags & SENSOR_FINVALID) == 0)
+               break;
           }
-        else
+#else
+        if (!tth->sensor_name)
           {
-             therms = ecore_file_ls("/sys/class/thermal");
-             if (therms)
-               {
-                  char *name;
-                  Eina_List *l;
+             Eina_List *l, *ll;
+             Mon *mon;
+             Temp *temp;
 
-                  EINA_LIST_FOREACH(therms, l, name)
-                    {
-                       if (!strncmp(name, "thermal", 7))
-                         {
-                            tth->sensor_type = SENSOR_TYPE_LINUX_SYS;
-                            tth->sensor_name = eina_stringshare_add(name);
-                            eina_list_free(therms);
-                            therms = NULL;
-                            break;
-                         }
-                    }
-                  EINA_LIST_FREE(therms, name) free(name);
-               }
-             else
+             eina_lock_take(&mons_lock);
+             EINA_LIST_FOREACH(mons, l, mon)
                {
-                  if (ecore_file_exists("/proc/omnibook/temperature"))
-                    {
-                       tth->sensor_type = SENSOR_TYPE_OMNIBOOK;
-                       tth->sensor_name = eina_stringshare_add("dummy");
-                    }
-                  else if 
(ecore_file_exists("/sys/devices/temperatures/sensor1_temperature"))
-                    {
-                       tth->sensor_type = SENSOR_TYPE_LINUX_PBOOK;
-                       tth->sensor_name = eina_stringshare_add("dummy");
-                    }
-                  else if 
(ecore_file_exists("/sys/devices/temperatures/cpu_temperature"))
+                  EINA_LIST_FOREACH(mon->temps, ll, temp)
                     {
-                       tth->sensor_type = SENSOR_TYPE_LINUX_MACMINI;
-                       tth->sensor_name = eina_stringshare_add("dummy");
-                    }
-                  else if 
(ecore_file_exists("/sys/devices/platform/coretemp.0/temp1_input"))
-                    {
-                       tth->sensor_type = SENSOR_TYPE_LINUX_INTELCORETEMP;
-                       tth->sensor_name = eina_stringshare_add("dummy");
-                    }
-                  else if 
(ecore_file_exists("/sys/devices/platform/thinkpad_hwmon/temp1_input"))
-                    {
-                       tth->sensor_type = SENSOR_TYPE_LINUX_THINKPAD;
-                       tth->sensor_name = eina_stringshare_add("dummy");
-                    }
-                  else
-                    {
-                       // try the i2c bus
-                       therms = temperature_get_bus_files("i2c");
-                       if (therms)
-                         {
-                            char *name;
-
-                            if ((name = eina_list_data_get(therms)))
-                              {
-                                 if (ecore_file_exists(name))
-                                   {
-                                      int len;
-
-                                      snprintf(path, sizeof(path),
-                                               "%s", 
ecore_file_file_get(name));
-                                      len = strlen(path);
-                                      if (len > 6) path[len - 6] = '\0';
-                                      tth->sensor_type = SENSOR_TYPE_LINUX_I2C;
-                                      tth->sensor_path = 
eina_stringshare_add(name);
-                                      tth->sensor_name = 
eina_stringshare_add(path);
-                                   }
-                              }
-                            EINA_LIST_FREE(therms, name) free(name);
-                         }
-                       if (!tth->sensor_path)
-                         {
-                            // try the pci bus
-                            therms = temperature_get_bus_files("pci");
-                            if (therms)
-                              {
-                                 char *name;
-
-                                 if ((name = eina_list_data_get(therms)))
-                                   {
-                                      if (ecore_file_exists(name))
-                                        {
-                                           int len;
-
-                                           snprintf(path, sizeof(path),
-                                                    "%s", 
ecore_file_file_get(name));
-                                           len = strlen(path);
-                                           if (len > 6) path[len - 6] = '\0';
-                                           tth->sensor_type = 
SENSOR_TYPE_LINUX_PCI;
-                                           tth->sensor_path = 
eina_stringshare_add(name);
-                                           
eina_stringshare_del(tth->sensor_name);
-                                           tth->sensor_name = 
eina_stringshare_add(path);
-                                        }
-                                   }
-                                 EINA_LIST_FREE(therms, name) free(name);
-                              }
-                         }
+                       tth->sensor_name = eina_stringshare_add(temp->path);
+                       break;
                     }
                }
+             eina_lock_release(&mons_lock);
           }
 #endif
      }
-   if ((tth->sensor_type) && (tth->sensor_name) && (!tth->sensor_path))
-     {
-        char *name;
-
-        switch (tth->sensor_type)
-          {
-           case SENSOR_TYPE_NONE:
-             break;
+}
 
-           case SENSOR_TYPE_FREEBSD:
+static int
+check(Tempthread *tth)
+{
 #if defined (__FreeBSD__) || defined(__DragonFly__)
-             len = sizeof(extn->mib) / sizeof(extn->mib[0]);
-             rc = sysctlnametomib(tth->sensor_name, extn->mib, &len);
-             if (rc == 0)
-               {
-                  extn->miblen = len;
-                  tth->sensor_path = eina_stringshare_add(tth->sensor_name);
-               }
-#endif
-             break;
-
-           case SENSOR_TYPE_OPENBSD:
-#ifdef __OpenBSD__
-             for (numt = 0; numt < snsrdev.maxnumt[SENSOR_TEMP]; numt++)
-               {
-                  extn->mib[4] = numt;
-                  slen = sizeof(snsr);
-                  if (sysctl(extn->mib, 5, &snsr, &slen, NULL, 0) == -1)
-                    continue;
-                  if (slen > 0 && (snsr.flags & SENSOR_FINVALID) == 0)
-                    {
-                       break;
-                    }
-               }
-#endif
-             break;
-
-           case SENSOR_TYPE_OMNIBOOK:
-             tth->sensor_path = 
eina_stringshare_add("/proc/omnibook/temperature");
-             break;
-
-           case SENSOR_TYPE_LINUX_MACMINI:
-             tth->sensor_path = 
eina_stringshare_add("/sys/devices/temperatures/cpu_temperature");
-             break;
-
-           case SENSOR_TYPE_LINUX_PBOOK:
-             tth->sensor_path = 
eina_stringshare_add("/sys/devices/temperatures/sensor1_temperature");
-             break;
-
-           case SENSOR_TYPE_LINUX_INTELCORETEMP:
-             tth->sensor_path = 
eina_stringshare_add("/sys/devices/platform/coretemp.0/temp1_input");
-             break;
-
-           case SENSOR_TYPE_LINUX_THINKPAD:
-             tth->sensor_path = 
eina_stringshare_add("/sys/devices/platform/thinkpad_hwmon/temp1_input");
-             break;
-
-           case SENSOR_TYPE_LINUX_I2C:
-             therms = ecore_file_ls("/sys/bus/i2c/devices");
-
-             EINA_LIST_FREE(therms, name)
-               {
-                  snprintf(path, sizeof(path),
-                           "/sys/bus/i2c/devices/%s/%s_input",
-                           name, tth->sensor_name);
-                  if (ecore_file_exists(path))
-                    {
-                       tth->sensor_path = eina_stringshare_add(path);
-                       /* We really only care about the first
-                        * one for the default. */
-                       break;
-                    }
-                  free(name);
-               }
-             break;
+   Extn *extn = tth->extn;
+   size_t len;
+   size_t ftemp = 0;
+   len = sizeof(ftemp);
+   if (sysctl(extn->mib, extn->miblen, &ftemp, &len, NULL, 0) == 0)
+     return (ftemp - 2732) / 10;
+#elif defined (__OpenBSD__)
+   Extn *extn = tth->extn;
+   if (sysctl(extn->mib, 5, &snsr, &slen, NULL, 0) != -1)
+     return (snsr.value - 273150000) / 1000000.0;
+#else
+   Eina_List *l, *ll;
+   Mon *mon;
+   Temp *temp;
 
-           case SENSOR_TYPE_LINUX_PCI:
-             therms = ecore_file_ls("/sys/bus/pci/devices");
+   _hwmon_update();
+   if (tth->sensor_name)
+     {
+        double t = 0.0;
 
-             EINA_LIST_FREE(therms, name)
+        eina_lock_take(&mons_lock);
+        EINA_LIST_FOREACH(mons, l, mon)
+          {
+             EINA_LIST_FOREACH(mon->temps, ll, temp)
                {
-                  snprintf(path, sizeof(path),
-                           "/sys/bus/pci/devices/%s/%s_input",
-                           name, tth->sensor_name);
-                  if (ecore_file_exists(path))
+                  if (!strcmp(tth->sensor_name, temp->path))
                     {
-                       tth->sensor_path = eina_stringshare_add(path);
-                       /* We really only care about the first
-                        * one for the default. */
+                       t =  temp->temp;
                        break;
                     }
-                  free(name);
                }
-             break;
+          }
+        eina_lock_release(&mons_lock);
+        return t;
+     }
+#endif
+   return -999;
+}
 
-           case SENSOR_TYPE_LINUX_ACPI:
-             snprintf(path, sizeof(path),
-                      "/proc/acpi/thermal_zone/%s/temperature",
-                      tth->sensor_name);
-             tth->sensor_path = eina_stringshare_add(path);
-             break;
+int
+temperature_tempget_get(Tempthread *tth)
+{
+   init(tth);
+   return check(tth);
+}
 
-           case SENSOR_TYPE_LINUX_SYS:
-             snprintf(path, sizeof(path),
-                      "/sys/class/thermal/%s/temp", tth->sensor_name);
-             tth->sensor_path = eina_stringshare_add(path);
-             break;
+Eina_List *
+temperature_tempget_sensor_list(void)
+{
+#if defined (__FreeBSD__) || defined(__DragonFly__)
+   return NULL;
+#elif defined (__OpenBSD__)
+   return NULL;
+#else
+   Eina_List *sensors = NULL, *l, *ll;
+   Sensor *sen;
+   Mon *mon;
+   Temp *temp;
+   char buf[256];
 
-           default:
-             break;
+   EINA_LIST_FOREACH(mons, l, mon)
+     {
+        EINA_LIST_FOREACH(mon->temps, ll, temp)
+          {
+             sen = calloc(1, sizeof(Sensor));
+             sen->name = eina_stringshare_add(temp->path);
+             snprintf(buf, sizeof(buf), "%s - %s",
+                      mon->label ? mon->label : mon->name,
+                      temp->label ? temp->label : temp->name);
+             sen->label = eina_stringshare_add(buf);
+             sensors = eina_list_append(sensors, sen);
           }
      }
+   return sensors;
+#endif
 }
 
-static int
-check(Tempthread *tth)
+void
+temperature_tempget_setup(void)
 {
-   FILE *f = NULL;
-   int ret = 0;
-   int temp = 0;
-   char buf[512];
 #if defined (__FreeBSD__) || defined(__DragonFly__)
-   size_t len;
-   size_t ftemp = 0;
-#endif
-#if defined (__FreeBSD__) || defined(__DragonFly__) || defined (__OpenBSD__)
-   Extn *extn = tth->extn;
+#elif defined (__OpenBSD__)
+#else
+   eina_lock_new(&mons_lock);
+   _hwmon_init();
 #endif
+}
 
-   /* TODO: Make standard parser. Seems to be two types of temperature string:
-    * - Somename: <temp> C
-    * - <temp>
-    */
-   switch (tth->sensor_type)
-     {
-      case SENSOR_TYPE_NONE:
-        /* TODO: Slow down poller? */
-        break;
-
-      case SENSOR_TYPE_FREEBSD:
+void
+temperature_tempget_clear(void)
+{
 #if defined (__FreeBSD__) || defined(__DragonFly__)
-        len = sizeof(ftemp);
-        if (sysctl(extn->mib, extn->miblen, &ftemp, &len, NULL, 0) == 0)
+#elif defined (__OpenBSD__)
+#else
+   Mon *mon;
+   Temp *temp;
+   Fan *fan;
+   Pwm *pwm;
+   Freq *freq;
+   Power *power;
+   Volt *volt;
+   Amp *amp;
+   Energy *energy;
+   Humid *humid;
+   Intrusion *intrusion;
+
+   eina_lock_take(&mons_lock);
+   EINA_LIST_FREE(mons, mon)
+     {
+        eina_stringshare_replace(&(mon->path), NULL);
+        eina_stringshare_replace(&(mon->name), NULL);
+        eina_stringshare_replace(&(mon->label), NULL);
+        EINA_LIST_FREE(mon->temps, temp)
           {
-             temp = (ftemp - 2732) / 10;
-             ret = 1;
+             eina_stringshare_replace(&(temp->path), NULL);
+             eina_stringshare_replace(&(temp->name), NULL);
+             eina_stringshare_replace(&(temp->label), NULL);
+             free(temp);
           }
-        else
-          goto error;
-#endif
-        break;
-
-      case SENSOR_TYPE_OPENBSD:
-#ifdef __OpenBSD__
-        if (sysctl(extn->mib, 5, &snsr, &slen, NULL, 0) != -1)
+        EINA_LIST_FREE(mon->fans, fan)
           {
-             temp = (snsr.value - 273150000) / 1000000.0;
-             ret = 1;
+             eina_stringshare_replace(&(fan->path), NULL);
+             eina_stringshare_replace(&(fan->name), NULL);
+             eina_stringshare_replace(&(fan->label), NULL);
+             free(fan);
           }
-        else
-          goto error;
-#endif
-        break;
-
-      case SENSOR_TYPE_OMNIBOOK:
-        f = fopen(tth->sensor_path, "r");
-        if (f)
+        EINA_LIST_FREE(mon->pwms, pwm)
           {
-             char dummy[4096];
-
-             if (fgets(buf, sizeof(buf), f) == NULL) goto error;
-             fclose(f);
-             f = NULL;
-             if (sscanf(buf, "%s %s %i", dummy, dummy, &temp) == 3)
-               ret = 1;
-             else
-               goto error;
+             eina_stringshare_replace(&(pwm->path), NULL);
+             eina_stringshare_replace(&(pwm->name), NULL);
+             free(fan);
           }
-        else
-          goto error;
-        break;
-
-      case SENSOR_TYPE_LINUX_MACMINI:
-      case SENSOR_TYPE_LINUX_PBOOK:
-        f = fopen(tth->sensor_path, "rb");
-        if (f)
+        EINA_LIST_FREE(mon->freqs, freq)
           {
-             if (fgets(buf, sizeof(buf), f) == NULL) goto error;
-             fclose(f);
-             f = NULL;
-             if (sscanf(buf, "%i", &temp) == 1)
-               ret = 1;
-             else
-               goto error;
+             eina_stringshare_replace(&(freq->path), NULL);
+             eina_stringshare_replace(&(freq->name), NULL);
+             eina_stringshare_replace(&(freq->label), NULL);
+             free(freq);
           }
-        else
-          goto error;
-        break;
-
-      case SENSOR_TYPE_LINUX_INTELCORETEMP:
-      case SENSOR_TYPE_LINUX_I2C:
-      case SENSOR_TYPE_LINUX_THINKPAD:
-        f = fopen(tth->sensor_path, "r");
-        if (f)
+        EINA_LIST_FREE(mon->powers, power)
           {
-             if (fgets(buf, sizeof(buf), f) == NULL) goto error;
-             fclose(f);
-             f = NULL;
-             /* actually read the temp */
-             if (sscanf(buf, "%i", &temp) == 1)
-               ret = 1;
-             else
-               goto error;
-             /* Hack for temp */
-             temp = temp / 1000;
+             eina_stringshare_replace(&(power->path), NULL);
+             eina_stringshare_replace(&(power->name), NULL);
+             free(power);
           }
-        else
-          goto error;
-        break;
-
-      case SENSOR_TYPE_LINUX_PCI:
-        f = fopen(tth->sensor_path, "r");
-        if (f)
+        EINA_LIST_FREE(mon->volts, volt)
           {
-             if (fgets(buf, sizeof(buf), f) == NULL) goto error;
-             fclose(f);
-             f = NULL;
-             /* actually read the temp */
-             if (sscanf(buf, "%i", &temp) == 1)
-               ret = 1;
-             else
-               goto error;
-             /* Hack for temp */
-             temp = temp / 1000;
+             eina_stringshare_replace(&(volt->path), NULL);
+             eina_stringshare_replace(&(volt->name), NULL);
+             eina_stringshare_replace(&(volt->label), NULL);
+             free(volt);
           }
-        else
-          goto error;
-        break;
-
-      case SENSOR_TYPE_LINUX_ACPI:
-        f = fopen(tth->sensor_path, "r");
-        if (f)
+        EINA_LIST_FREE(mon->amps, amp)
           {
-             char *p, *q;
-
-             if (fgets(buf, sizeof(buf), f) == NULL) goto error;
-             fclose(f);
-             f = NULL;
-             p = strchr(buf, ':');
-             if (p)
-               {
-                  p++;
-                  while (*p == ' ')
-                    p++;
-                  q = strchr(p, ' ');
-                  if (q) *q = 0;
-                  temp = atoi(p);
-                  ret = 1;
-               }
-             else
-               goto error;
+             eina_stringshare_replace(&(amp->path), NULL);
+             eina_stringshare_replace(&(amp->name), NULL);
+             free(amp);
           }
-        else
-          goto error;
-        break;
-
-      case SENSOR_TYPE_LINUX_SYS:
-        f = fopen(tth->sensor_path, "r");
-        if (f)
+        EINA_LIST_FREE(mon->energies, energy)
           {
-             if (fgets(buf, sizeof(buf), f) == NULL) goto error;
-             fclose(f);
-             f = NULL;
-             temp = atoi(buf);
-             temp /= 1000;
-             ret = 1;
+             eina_stringshare_replace(&(energy->path), NULL);
+             eina_stringshare_replace(&(energy->name), NULL);
+             free(energy);
           }
-        else
-          goto error;
-        break;
-
-      default:
-        break;
+        EINA_LIST_FREE(mon->humids, humid)
+          {
+             eina_stringshare_replace(&(humid->path), NULL);
+             eina_stringshare_replace(&(humid->name), NULL);
+             free(humid);
+          }
+        EINA_LIST_FREE(mon->intrusions, intrusion)
+          {
+             eina_stringshare_replace(&(intrusion->path), NULL);
+             eina_stringshare_replace(&(intrusion->name), NULL);
+             free(intrusion);
+          }
+        free(mon);
      }
-
-   if (ret) return temp;
-
-   return -999;
-error:
-   if (f) fclose(f);
-   tth->sensor_type = SENSOR_TYPE_NONE;
-   eina_stringshare_del(tth->sensor_name);
-   tth->sensor_name = NULL;
-   eina_stringshare_del(tth->sensor_path);
-   tth->sensor_path = NULL;
-   return -999;
-}
-
-int
-temperature_tempget_get(Tempthread *tth)
-{
-   int temp;
-
-   init(tth);
-   temp = check(tth);
-   return temp;
+   eina_lock_release(&mons_lock);
+   // extra lock take to cover race cond for thread
+   eina_lock_take(&mons_lock);
+   eina_lock_release(&mons_lock);
+   eina_lock_free(&mons_lock);
+#endif
 }

-- 


Reply via email to