[haiku-commits] haiku: hrev54094 - src/add-ons/kernel/drivers/sensor/acpi_als src/add-ons/kernel/generic/smbios src/add-ons/kernel/drivers/wmi headers/private/drivers

  • From: Jérôme Duval <jerome.duval@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 27 Apr 2020 03:38:45 -0400 (EDT)

hrev54094 adds 3 changesets to branch 'master'
old head: bd3b70048428cb3b298bf61de479e12a41aa23a7
new head: 03f4263ea50930477c3f9a5137acd82ba8415f2a
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=03f4263ea509+%5Ebd3b70048428

----------------------------------------------------------------------------

97f2b91169c1: smbios: add module to match SMBios vendor and product
  
  Change-Id: Ib7848da1c22c42a1a9030891159f4e852c6c1ecd
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/2503
  Reviewed-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

ceb94d008025: wmi: some ASUS laptops need have ALS forced enabled
  
  Change-Id: Ie0752419b1e60d78cdfe60e5b35303a09db10400
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/2504
  Reviewed-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

03f4263ea509: acpi_als: driver for ALS ACPI devices
  
  Change-Id: I24068c7b3e1c5863d39d0a805a32acfeb93ad422
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/2505
  Reviewed-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

                                   [ Jérôme Duval <jerome.duval@xxxxxxxxx> ]

----------------------------------------------------------------------------

12 files changed, 706 insertions(+), 3 deletions(-)
headers/private/drivers/smbios.h                 |  23 ++
src/add-ons/kernel/drivers/Jamfile               |   1 +
src/add-ons/kernel/drivers/sensor/Jamfile        |   4 +
.../kernel/drivers/sensor/acpi_als/Jamfile       |  11 +
.../kernel/drivers/sensor/acpi_als/acpi_als.cpp  | 370 +++++++++++++++++++
src/add-ons/kernel/drivers/wmi/Jamfile           |   2 +-
src/add-ons/kernel/drivers/wmi/WMIACPI.cpp       |   3 +-
src/add-ons/kernel/drivers/wmi/WMIAsus.cpp       |  27 +-
src/add-ons/kernel/drivers/wmi/WMIPrivate.h      |   2 +
src/add-ons/kernel/generic/Jamfile               |   1 +
src/add-ons/kernel/generic/smbios/Jamfile        |   8 +
src/add-ons/kernel/generic/smbios/smbios.cpp     | 257 +++++++++++++

############################################################################

Commit:      97f2b91169c13d1fde0403013f366c44267915be
URL:         https://git.haiku-os.org/haiku/commit/?id=97f2b91169c1
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Mon Apr 20 11:53:27 2020 UTC

smbios: add module to match SMBios vendor and product

Change-Id: Ib7848da1c22c42a1a9030891159f4e852c6c1ecd
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2503
Reviewed-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

----------------------------------------------------------------------------

diff --git a/headers/private/drivers/smbios.h b/headers/private/drivers/smbios.h
new file mode 100644
index 0000000000..0c7f557eb1
--- /dev/null
+++ b/headers/private/drivers/smbios.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2020, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _SMBIOS_MODULE_H_
+#define _SMBIOS_MODULE_H_
+
+
+#include <OS.h>
+#include <module.h>
+
+
+typedef struct smbios_module_info {
+       module_info     info;
+
+       bool    (*match_vendor_product)(const char* vendor, const char* 
product);
+} smbios_module_info;
+
+
+#define SMBIOS_MODULE_NAME "generic/smbios/driver_v1"
+
+
+#endif // _SMBIOS_MODULE_H_
diff --git a/src/add-ons/kernel/generic/Jamfile 
b/src/add-ons/kernel/generic/Jamfile
index 89d57149bf..04f35b985e 100644
--- a/src/add-ons/kernel/generic/Jamfile
+++ b/src/add-ons/kernel/generic/Jamfile
@@ -6,4 +6,5 @@ SubInclude HAIKU_TOP src add-ons kernel generic dpc ;
 SubInclude HAIKU_TOP src add-ons kernel generic locked_pool ;
 SubInclude HAIKU_TOP src add-ons kernel generic mpu401 ;
 SubInclude HAIKU_TOP src add-ons kernel generic scsi_periph ;
+SubInclude HAIKU_TOP src add-ons kernel generic smbios ;
 SubInclude HAIKU_TOP src add-ons kernel generic tty ;
diff --git a/src/add-ons/kernel/generic/smbios/Jamfile 
b/src/add-ons/kernel/generic/smbios/Jamfile
new file mode 100644
index 0000000000..2b24cd19d7
--- /dev/null
+++ b/src/add-ons/kernel/generic/smbios/Jamfile
@@ -0,0 +1,8 @@
+SubDir HAIKU_TOP src add-ons kernel generic smbios ;
+
+UsePrivateHeaders drivers ;
+UsePrivateKernelHeaders ;
+
+KernelAddon smbios :
+       smbios.cpp
+       ;
diff --git a/src/add-ons/kernel/generic/smbios/smbios.cpp 
b/src/add-ons/kernel/generic/smbios/smbios.cpp
new file mode 100644
index 0000000000..429f107cdf
--- /dev/null
+++ b/src/add-ons/kernel/generic/smbios/smbios.cpp
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2020, Jérôme Duval, jerome.duval@xxxxxxxxx.
+ * Distributed under the terms of the MIT license.
+ */
+
+
+#include "smbios.h"
+
+#include <device_manager.h>
+#include <KernelExport.h>
+#include <module.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <vm/vm.h>
+
+
+#define TRACE_SMBIOS
+#ifdef TRACE_SMBIOS
+#      define TRACE(x...) dprintf (x)
+#else
+#      define TRACE(x...) ;
+#endif
+
+
+static device_manager_info* gDeviceManager;
+static char* sHardwareVendor = NULL;
+static char* sHardwareProduct = NULL;
+
+struct smbios {
+       uint32          anchor_string;
+       uint8           entry_point_checksum;
+       uint8           entry_point_length;
+       struct {
+               uint8   major;
+               uint8   minor;
+       } version;
+       uint16          maximum_size;
+       uint8           entry_point_revision;
+       uint8           formatted_area[5];
+
+       uint8           dmi_anchor_string[5];
+       uint8           intermediate_checksum;
+       uint16          structure_table_size;
+       uint32          structure_table;
+       uint16          num_structures;
+       uint8           bcd_revision;
+} _PACKED;
+
+
+struct smbios3 {
+       uint8           anchor_string[5];
+       uint8           entry_point_checksum;
+       uint8           entry_point_length;
+       struct {
+               uint8   major;
+               uint8   minor;
+               uint8   doc;
+       } version;
+       uint8           entry_point_revision;
+       uint8           reserved;
+       uint32          structure_table_size;
+       uint64          structure_table;
+} _PACKED;
+
+
+struct smbios_structure_header {
+       uint8           type;
+       uint8           length;
+       uint16          handle;
+} _PACKED;
+
+
+#define SMBIOS "_SM_"
+#define SMBIOS3        "_SM3_"
+
+enum {
+       SMBIOS_TYPE_BIOS        = 0,
+       SMBIOS_TYPE_SYSTEM,
+};
+
+
+struct smbios_system {
+       struct smbios_structure_header header;
+       uint8           manufacturer;
+       uint8           product_name;
+       uint8           version;
+       uint8           serial_number;
+       uint8           uuid[16];
+       uint8           wakeup_type;
+       uint8           sku_number;
+       uint8           family;
+} _PACKED;
+
+
+static bool
+smbios_match_vendor_product(const char* vendor, const char* product)
+{
+       if (vendor == NULL && product == NULL)
+               return false;
+
+       bool match = true;
+       if (vendor != NULL && sHardwareVendor != NULL)
+               match = strcmp(vendor, sHardwareVendor) == 0;
+       if (match && product != NULL && sHardwareProduct != NULL)
+               match = strcmp(product, sHardwareProduct) == 0;
+       return match;
+}
+
+
+static const char *
+smbios_get_string(struct smbios_structure_header* table, uint8* tableEnd,
+       uint8 index)
+{
+       uint8* addr = (uint8*)table + table->length;
+       uint8 i = 1;
+       for (; addr < tableEnd && i < index && *addr != 0; i++) {
+               while (*addr != 0 && addr < tableEnd)
+                       addr++;
+               addr++;
+       }
+       if (i == index)
+               return (const char*)addr;
+
+       return NULL;
+}
+
+
+static void
+smbios_scan()
+{
+       TRACE("smbios_scan\n");
+       static bool scanDone = false;
+       if (scanDone)
+               return;
+
+       // map SMBIOS area 0xf0000 - 0xfffff
+       addr_t smBiosBase;
+       area_id smbiosArea = map_physical_memory("pc bios", 0xf0000, 0x10000,
+               B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA, (void **)&smBiosBase);
+       if (smbiosArea < 0)
+               return;
+
+       struct smbios *smbios = NULL;
+       struct smbios3 *smbios3 = NULL;
+       for (addr_t offset = 0; offset <= 0xffe0; offset += 0x10) {
+               void* p = (void*)(smBiosBase + offset);
+               if (memcmp(p, SMBIOS3, 5) == 0) {
+                       smbios3 = (struct smbios3 *)p;
+                       break;
+               } else if (memcmp(p, SMBIOS, 4) == 0) {
+                       smbios = (struct smbios *)p;
+               }
+       }
+
+       phys_addr_t tablePhysAddr = 0;
+       size_t tablePhysLength = 0;
+       void* table;
+       status_t status;
+       uint8* tableEnd;
+
+       if (smbios != NULL) {
+               tablePhysAddr = smbios->structure_table;
+               tablePhysLength = smbios->structure_table_size;
+       } else if (smbios3 != NULL) {
+               tablePhysAddr = smbios3->structure_table;
+               tablePhysLength = smbios3->structure_table_size;
+       }
+
+       if (tablePhysAddr == 0)
+               goto err;
+
+       table = malloc(tablePhysLength);
+       if (table == NULL)
+               goto err;
+       status = vm_memcpy_from_physical(table, tablePhysAddr,
+               tablePhysLength, false);
+       if (status != B_OK)
+               goto err;
+
+       tableEnd = (uint8*)table + tablePhysLength;
+       for (uint8* addr = (uint8*)table;
+               (addr + sizeof(struct smbios_structure_header)) < tableEnd;) {
+               struct smbios_structure_header* table
+                       = (struct smbios_structure_header*)addr;
+
+               if (table->type == SMBIOS_TYPE_SYSTEM) {
+                       struct smbios_system *system = (struct 
smbios_system*)table;
+                       TRACE("found System Information at %p\n", table);
+                       TRACE("found vendor %u product %u\n", 
system->manufacturer,
+                               system->product_name);
+                       const char* vendor = smbios_get_string(table, tableEnd,
+                               system->manufacturer);
+                       const char* product = smbios_get_string(table, tableEnd,
+                               system->product_name);
+                       if (vendor != NULL)
+                               sHardwareVendor = strdup(vendor);
+                       if (product != NULL)
+                               sHardwareProduct = strdup(product);
+                       break;
+               }
+               addr += table->length;
+               for (; addr + 1 < tableEnd; addr++) {
+                       if (*addr == 0 && *(addr + 1) == 0)
+                               break;
+               }
+               addr += 2;
+       }
+
+       scanDone = true;
+       TRACE("smbios_scan found vendor %s product %s\n", sHardwareVendor,
+               sHardwareProduct);
+err:
+       delete_area(smbiosArea);
+}
+
+
+static status_t
+std_ops(int32 op, ...)
+{
+       switch (op) {
+               case B_MODULE_INIT:
+                       smbios_scan();
+                       return B_OK;
+               case B_MODULE_UNINIT:
+                       free(sHardwareVendor);
+                       free(sHardwareProduct);
+                       return B_OK;
+               default:
+                       return B_ERROR;
+       }
+}
+
+
+
+module_dependency module_dependencies[] = {
+       {B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager},
+       {}
+};
+
+
+static smbios_module_info sSMBIOSModule = {
+       {
+               SMBIOS_MODULE_NAME,
+               B_KEEP_LOADED,
+               std_ops
+       },
+
+       smbios_match_vendor_product,
+};
+
+
+module_info *modules[] = {
+       (module_info*)&sSMBIOSModule,
+       NULL
+};

############################################################################

Commit:      ceb94d008025cc83a8ff76666576d1ff33777604
URL:         https://git.haiku-os.org/haiku/commit/?id=ceb94d008025
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Mon Apr 20 11:55:26 2020 UTC

wmi: some ASUS laptops need have ALS forced enabled

Change-Id: Ie0752419b1e60d78cdfe60e5b35303a09db10400
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2504
Reviewed-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/drivers/wmi/Jamfile 
b/src/add-ons/kernel/drivers/wmi/Jamfile
index dcb773e130..c932205b98 100644
--- a/src/add-ons/kernel/drivers/wmi/Jamfile
+++ b/src/add-ons/kernel/drivers/wmi/Jamfile
@@ -1,6 +1,6 @@
 SubDir HAIKU_TOP src add-ons kernel drivers wmi ;
 
-UsePrivateHeaders wmi ;
+UsePrivateHeaders drivers wmi ;
 UsePrivateKernelHeaders ;
 
 KernelAddon wmi :
diff --git a/src/add-ons/kernel/drivers/wmi/WMIACPI.cpp 
b/src/add-ons/kernel/drivers/wmi/WMIACPI.cpp
index 4d9c3c496b..1838d4d9d8 100644
--- a/src/add-ons/kernel/drivers/wmi/WMIACPI.cpp
+++ b/src/add-ons/kernel/drivers/wmi/WMIACPI.cpp
@@ -17,6 +17,7 @@
 
 
 device_manager_info *gDeviceManager;
+smbios_module_info *gSMBios;
 
 
 acpi_status wmi_acpi_adr_space_handler(uint32 function,
@@ -453,9 +454,9 @@ wmi_acpi_register_child_devices(void *cookie)
 }
 
 
-
 module_dependency module_dependencies[] = {
        { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
+       { SMBIOS_MODULE_NAME, (module_info**)&gSMBios },
        {}
 };
 
diff --git a/src/add-ons/kernel/drivers/wmi/WMIAsus.cpp 
b/src/add-ons/kernel/drivers/wmi/WMIAsus.cpp
index 80d84eb8a7..e72daebcaa 100644
--- a/src/add-ons/kernel/drivers/wmi/WMIAsus.cpp
+++ b/src/add-ons/kernel/drivers/wmi/WMIAsus.cpp
@@ -19,6 +19,8 @@
 #define ASUS_WMI_METHODID_DSTS         0x53545344
 #define ASUS_WMI_METHODID_DEVS         0x53564544
 
+
+#define ASUS_WMI_DEVID_ALS_ENABLE              0x00050001
 #define ASUS_WMI_DEVID_BRIGHTNESS              0x00050012
 #define ASUS_WMI_DEVID_KBD_BACKLIGHT   0x00050021
 
@@ -37,12 +39,14 @@ private:
        static  void                            _NotifyHandler(acpi_handle 
handle,
                                                                        uint32 
notify, void *context);
                        void                            _Notify(acpi_handle 
handle, uint32 notify);
+                       status_t                        _EnableAls(uint32 
enable);
 private:
                        device_node*            fNode;
                        wmi_device_interface* wmi;
                        wmi_device                      wmi_cookie;
                        uint32                          fDstsID;
                        const char*                     fEventGuidString;
+                       bool                            fEnableALS;
 };
 
 
@@ -51,7 +55,8 @@ WMIAsus::WMIAsus(device_node *node)
        :
        fNode(node),
        fDstsID(ASUS_WMI_METHODID_DSTS),
-       fEventGuidString(NULL)
+       fEventGuidString(NULL),
+       fEnableALS(false)
 {
        CALLED();
 
@@ -77,6 +82,13 @@ WMIAsus::WMIAsus(device_node *node)
                TRACE("_SFUN: %x\n", value);
        }
 
+       // some ASUS laptops need to be ALS forced
+       fEnableALS =
+               gSMBios->match_vendor_product("ASUSTeK COMPUTER INC.", 
"UX430UAR");
+       if (fEnableALS && _EnableAls(1) == B_OK) {
+               TRACE("ALSC enabled\n");
+       }
+
        // install event handler
        if (wmi->install_event_handler(wmi_cookie, ACPI_ASUS_WMI_EVENT_GUID,
                _NotifyHandler, this) == B_OK) {
@@ -87,6 +99,11 @@ WMIAsus::WMIAsus(device_node *node)
 
 WMIAsus::~WMIAsus()
 {
+       // for ALS
+       if (fEnableALS && _EnableAls(0) == B_OK) {
+               TRACE("ALSC disabled\n");
+       }
+
        if (fEventGuidString != NULL)
                wmi->remove_event_handler(wmi_cookie, fEventGuidString);
 }
@@ -119,6 +136,14 @@ WMIAsus::_EvaluateMethod(uint32 methodId, uint32 arg0, 
uint32 arg1,
 }
 
 
+status_t
+WMIAsus::_EnableAls(uint32 enable)
+{
+       CALLED();
+       return _SetDevState(ASUS_WMI_DEVID_ALS_ENABLE, enable, NULL);
+}
+
+
 status_t
 WMIAsus::_GetDevState(uint32 devId, uint32 *value)
 {
diff --git a/src/add-ons/kernel/drivers/wmi/WMIPrivate.h 
b/src/add-ons/kernel/drivers/wmi/WMIPrivate.h
index ec8be7f930..b9d620b99d 100644
--- a/src/add-ons/kernel/drivers/wmi/WMIPrivate.h
+++ b/src/add-ons/kernel/drivers/wmi/WMIPrivate.h
@@ -12,6 +12,7 @@
 #include <string.h>
 
 #include <lock.h>
+#include <smbios.h>
 #include <util/AutoLock.h>
 #include <wmi.h>
 
@@ -43,6 +44,7 @@ class WMIDevice;
 
 
 extern device_manager_info *gDeviceManager;
+extern smbios_module_info *gSMBios;
 extern wmi_device_interface gWMIDeviceModule;
 extern driver_module_info gWMIAsusDriverModule;
 

############################################################################

Revision:    hrev54094
Commit:      03f4263ea50930477c3f9a5137acd82ba8415f2a
URL:         https://git.haiku-os.org/haiku/commit/?id=03f4263ea509
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Fri Apr 17 18:37:33 2020 UTC

acpi_als: driver for ALS ACPI devices

Change-Id: I24068c7b3e1c5863d39d0a805a32acfeb93ad422
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2505
Reviewed-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/drivers/Jamfile 
b/src/add-ons/kernel/drivers/Jamfile
index 7bbda5d0ea..96d31f5013 100644
--- a/src/add-ons/kernel/drivers/Jamfile
+++ b/src/add-ons/kernel/drivers/Jamfile
@@ -15,6 +15,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers misc ;
 SubInclude HAIKU_TOP src add-ons kernel drivers network ;
 SubInclude HAIKU_TOP src add-ons kernel drivers ports ;
 SubInclude HAIKU_TOP src add-ons kernel drivers power ;
+SubInclude HAIKU_TOP src add-ons kernel drivers sensor ;
 SubInclude HAIKU_TOP src add-ons kernel drivers timer ;
 SubInclude HAIKU_TOP src add-ons kernel drivers tty ;
 SubInclude HAIKU_TOP src add-ons kernel drivers video ;
diff --git a/src/add-ons/kernel/drivers/sensor/Jamfile 
b/src/add-ons/kernel/drivers/sensor/Jamfile
new file mode 100644
index 0000000000..52011f6c26
--- /dev/null
+++ b/src/add-ons/kernel/drivers/sensor/Jamfile
@@ -0,0 +1,4 @@
+SubDir HAIKU_TOP src add-ons kernel drivers sensor ;
+
+SubInclude HAIKU_TOP src add-ons kernel drivers sensor acpi_als ;
+
diff --git a/src/add-ons/kernel/drivers/sensor/acpi_als/Jamfile 
b/src/add-ons/kernel/drivers/sensor/acpi_als/Jamfile
new file mode 100644
index 0000000000..242b311f23
--- /dev/null
+++ b/src/add-ons/kernel/drivers/sensor/acpi_als/Jamfile
@@ -0,0 +1,11 @@
+SubDir HAIKU_TOP src add-ons kernel drivers sensor acpi_als ;
+
+UsePrivateKernelHeaders ;
+
+SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) $(DOTDOT) bus_managers 
acpi acpica include ] ;
+SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) $(DOTDOT) bus_managers 
acpi acpica include platform ] ;
+
+KernelAddon acpi_als :
+       acpi_als.cpp
+       ;
+
diff --git a/src/add-ons/kernel/drivers/sensor/acpi_als/acpi_als.cpp 
b/src/add-ons/kernel/drivers/sensor/acpi_als/acpi_als.cpp
new file mode 100644
index 0000000000..5ff5367956
--- /dev/null
+++ b/src/add-ons/kernel/drivers/sensor/acpi_als/acpi_als.cpp
@@ -0,0 +1,370 @@
+/*
+ * Copyright 2020, Jérôme Duval, jerome.duval@xxxxxxxxx.
+ * Distributed under the terms of the MIT license.
+ */
+
+
+#include <ACPI.h>
+#include <condition_variable.h>
+#include <Drivers.h>
+#include <Errors.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <kernel.h>
+
+
+extern "C" {
+#      include "acpi.h"
+}
+
+
+struct als_driver_cookie {
+       device_node*                            node;
+       acpi_device_module_info*        acpi;
+       acpi_device                                     acpi_cookie;
+};
+
+
+struct als_device_cookie {
+       als_driver_cookie*              driver_cookie;
+       int32                                   stop_watching;
+};
+
+
+#define ACPI_ALS_DRIVER_NAME "drivers/sensor/acpi_als/driver_v1"
+#define ACPI_ALS_DEVICE_NAME "drivers/sensor/acpi_als/device_v1"
+
+/* Base Namespace devices are published to */
+#define ACPI_ALS_BASENAME "sensor/acpi_als/%d"
+
+// name of pnp generator of path ids
+#define ACPI_ALS_PATHID_GENERATOR "acpi_als/path_id"
+
+#define ACPI_NAME_ALS "ACPI0008"
+
+#define TRACE_ALS
+#ifdef TRACE_ALS
+#      define TRACE(x...) dprintf("acpi_als: " x)
+#else
+#      define TRACE(x...)
+#endif
+#define ERROR(x...) dprintf("acpi_als: " x)
+
+
+static device_manager_info *sDeviceManager;
+static ConditionVariable sALSCondition;
+
+
+static status_t
+acpi_GetInteger(als_driver_cookie *device,
+       const char* path, uint64* number)
+{
+       acpi_data buf;
+       acpi_object_type object;
+       buf.pointer = &object;
+       buf.length = sizeof(acpi_object_type);
+
+       // Assume that what we've been pointed at is an Integer object, or
+       // a method that will return an Integer.
+       status_t status = device->acpi->evaluate_method(device->acpi_cookie, 
path,
+               NULL, &buf);
+       if (status == B_OK) {
+               if (object.object_type == ACPI_TYPE_INTEGER)
+                       *number = object.integer.integer;
+               else
+                       status = B_BAD_VALUE;
+       }
+       return status;
+}
+
+
+void
+als_notify_handler(acpi_handle device, uint32 value, void *context)
+{
+       TRACE("als_notify_handler event 0x%" B_PRIx32 "\n", value);
+       sALSCondition.NotifyAll();
+}
+
+
+//     #pragma mark - device module API
+
+
+static status_t
+acpi_als_init_device(void *driverCookie, void **cookie)
+{
+       *cookie = driverCookie;
+       return B_OK;
+}
+
+
+static void
+acpi_als_uninit_device(void *_cookie)
+{
+
+}
+
+
+static status_t
+acpi_als_open(void *initCookie, const char *path, int flags, void** cookie)
+{
+       als_device_cookie *device;
+       device = (als_device_cookie*)calloc(1, sizeof(als_device_cookie));
+       if (device == NULL)
+               return B_NO_MEMORY;
+
+       device->driver_cookie = (als_driver_cookie*)initCookie;
+       device->stop_watching = 0;
+
+       *cookie = device;
+
+       return B_OK;
+}
+
+
+static status_t
+acpi_als_close(void* cookie)
+{
+       return B_OK;
+}
+
+
+static status_t
+acpi_als_read(void* _cookie, off_t position, void *buffer, size_t* numBytes)
+{
+       if (*numBytes < 1)
+               return B_IO_ERROR;
+
+       als_device_cookie *device = (als_device_cookie*)_cookie;
+
+       if (position == 0) {
+               char string[10];
+               uint64 luminance = 0;
+               status_t status = acpi_GetInteger(device->driver_cookie,
+                       "_ALI", &luminance);
+               if (status != B_OK)
+                       return B_ERROR;
+               snprintf(string, sizeof(string), "%" B_PRIu64 "\n", luminance);
+               size_t max_len = user_strlcpy((char*)buffer, string, *numBytes);
+               if (max_len < B_OK)
+                       return B_BAD_ADDRESS;
+               *numBytes = max_len;
+       } else
+               *numBytes = 0;
+
+       return B_OK;
+}
+
+
+static status_t
+acpi_als_write(void* cookie, off_t position, const void* buffer,
+       size_t* numBytes)
+{
+       return B_ERROR;
+}
+
+
+static status_t
+acpi_als_control(void* _cookie, uint32 op, void* arg, size_t len)
+{
+       //als_device_cookie* device = (als_device_cookie*)_cookie;
+
+       return B_DEV_INVALID_IOCTL;
+}
+
+
+static status_t
+acpi_als_free(void* cookie)
+{
+       als_device_cookie* device = (als_device_cookie*)cookie;
+       free(device);
+       return B_OK;
+}
+
+
+//     #pragma mark - driver module API
+
+
+static float
+acpi_als_support(device_node *parent)
+{
+       // make sure parent is really the ACPI bus manager
+       const char *bus;
+       if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
+               return -1;
+
+       if (strcmp(bus, "acpi"))
+               return 0.0;
+
+       // check whether it's really a device
+       uint32 device_type;
+       if (sDeviceManager->get_attr_uint32(parent, ACPI_DEVICE_TYPE_ITEM,
+                       &device_type, false) != B_OK
+               || device_type != ACPI_TYPE_DEVICE) {
+               return 0.0;
+       }
+
+       // check whether it's a als device
+       const char *name;
+       if (sDeviceManager->get_attr_string(parent, ACPI_DEVICE_HID_ITEM, &name,
+               false) != B_OK || strcmp(name, ACPI_NAME_ALS)) {
+               return 0.0;
+       }
+
+       return 0.6;
+}
+
+
+static status_t
+acpi_als_register_device(device_node *node)
+{
+       device_attr attrs[] = {
+               { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "ACPI ALS" }},
+               { NULL }
+       };
+
+       return sDeviceManager->register_node(node, ACPI_ALS_DRIVER_NAME, attrs,
+               NULL, NULL);
+}
+
+
+static status_t
+acpi_als_init_driver(device_node *node, void **driverCookie)
+{
+       als_driver_cookie *device;
+       device = (als_driver_cookie *)calloc(1, sizeof(als_driver_cookie));
+       if (device == NULL)
+               return B_NO_MEMORY;
+
+       *driverCookie = device;
+
+       device->node = node;
+
+       device_node *parent;
+       parent = sDeviceManager->get_parent_node(node);
+       sDeviceManager->get_driver(parent, (driver_module_info **)&device->acpi,
+               (void **)&device->acpi_cookie);
+
+#ifdef TRACE_ALS
+       const char* device_path;
+       if (sDeviceManager->get_attr_string(parent, ACPI_DEVICE_PATH_ITEM,
+               &device_path, false) == B_OK) {
+               TRACE("acpi_als_init_driver %s\n", device_path);
+       }
+#endif
+
+       sDeviceManager->put_node(parent);
+
+       uint64 sta;
+       status_t status = acpi_GetInteger(device, "_STA", &sta);
+       uint64 mask = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED
+               | ACPI_STA_DEVICE_FUNCTIONING;
+       if (status == B_OK && (sta & mask) != mask) {
+               ERROR("acpi_als_init_driver device disabled\n");
+               return B_ERROR;
+       }
+
+       uint64 luminance;
+       status = acpi_GetInteger(device, "_ALI", &luminance);
+       if (status != B_OK) {
+               ERROR("acpi_als_init_driver error when calling _ALI\n");
+               return B_ERROR;
+       }
+
+       // install notify handler
+       device->acpi->install_notify_handler(device->acpi_cookie,
+               ACPI_ALL_NOTIFY, als_notify_handler, device);
+
+       return B_OK;
+}
+
+
+static void
+acpi_als_uninit_driver(void *driverCookie)
+{
+       TRACE("acpi_als_uninit_driver\n");
+       als_driver_cookie *device = (als_driver_cookie*)driverCookie;
+
+       device->acpi->remove_notify_handler(device->acpi_cookie,
+               ACPI_ALL_NOTIFY, als_notify_handler);
+
+       free(device);
+}
+
+
+static status_t
+acpi_als_register_child_devices(void *cookie)
+{
+       als_driver_cookie *device = (als_driver_cookie*)cookie;
+
+       int pathID = sDeviceManager->create_id(ACPI_ALS_PATHID_GENERATOR);
+       if (pathID < 0) {
+               ERROR("register_child_devices: couldn't create a path_id\n");
+               return B_ERROR;
+       }
+
+       char name[128];
+       snprintf(name, sizeof(name), ACPI_ALS_BASENAME, pathID);
+
+       return sDeviceManager->publish_device(device->node, name,
+               ACPI_ALS_DEVICE_NAME);
+}
+
+
+
+
+
+
+module_dependency module_dependencies[] = {
+       { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager },
+       {}
+};
+
+
+driver_module_info acpi_als_driver_module = {
+       {
+               ACPI_ALS_DRIVER_NAME,
+               0,
+               NULL
+       },
+
+       acpi_als_support,
+       acpi_als_register_device,
+       acpi_als_init_driver,
+       acpi_als_uninit_driver,
+       acpi_als_register_child_devices,
+       NULL,   // rescan
+       NULL,   // removed
+};
+
+
+struct device_module_info acpi_als_device_module = {
+       {
+               ACPI_ALS_DEVICE_NAME,
+               0,
+               NULL
+       },
+
+       acpi_als_init_device,
+       acpi_als_uninit_device,
+       NULL,
+
+       acpi_als_open,
+       acpi_als_close,
+       acpi_als_free,
+       acpi_als_read,
+       acpi_als_write,
+       NULL,
+       acpi_als_control,
+
+       NULL,
+       NULL
+};
+
+module_info *modules[] = {
+       (module_info *)&acpi_als_driver_module,
+       (module_info *)&acpi_als_device_module,
+       NULL
+};


Other related posts:

  • » [haiku-commits] haiku: hrev54094 - src/add-ons/kernel/drivers/sensor/acpi_als src/add-ons/kernel/generic/smbios src/add-ons/kernel/drivers/wmi headers/private/drivers - Jérôme Duval