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
+};