14035Sphitran /***************************************************************************
24035Sphitran *
34035Sphitran * devinfo_acpi : acpi devices
44035Sphitran *
56573Sphitran * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
64035Sphitran * Use is subject to license terms.
74035Sphitran *
84035Sphitran * Licensed under the Academic Free License version 2.1
94035Sphitran *
104035Sphitran **************************************************************************/
114035Sphitran
124035Sphitran #ifdef HAVE_CONFIG_H
134035Sphitran #include <config.h>
144035Sphitran #endif
154035Sphitran
164035Sphitran #include <stdio.h>
174035Sphitran #include <string.h>
184035Sphitran #include <sys/utsname.h>
194035Sphitran #include <libdevinfo.h>
204035Sphitran #include <sys/mkdev.h>
214035Sphitran #include <sys/stat.h>
224035Sphitran #include <unistd.h>
236573Sphitran #include <sys/sysevent/dev.h>
246573Sphitran #include <sys/sysevent/pwrctl.h>
254035Sphitran
264035Sphitran #include "../osspec.h"
274035Sphitran #include "../logger.h"
284035Sphitran #include "../hald.h"
294035Sphitran #include "../hald_dbus.h"
304035Sphitran #include "../device_info.h"
314035Sphitran #include "../util.h"
324035Sphitran #include "../hald_runner.h"
334035Sphitran #include "devinfo_acpi.h"
344035Sphitran
35*7651SPhi.Tran@Sun.COM #define DEVINFO_PROBE_ACPI_TIMEOUT 30000
364035Sphitran
374035Sphitran static HalDevice *devinfo_acpi_add(HalDevice *, di_node_t, char *, char *);
386573Sphitran static HalDevice *devinfo_power_button_add(HalDevice *parent, di_node_t node,
396573Sphitran char *devfs_path, char *device_type);
406573Sphitran static void devinfo_battery_rescan_probing_done(HalDevice *d, guint32 exit_type,
416573Sphitran gint return_code, char **error, gpointer userdata1, gpointer userdata2);
424035Sphitran
434035Sphitran DevinfoDevHandler devinfo_acpi_handler = {
444035Sphitran devinfo_acpi_add,
454035Sphitran NULL,
464035Sphitran NULL,
474035Sphitran NULL,
484035Sphitran NULL,
497137Sphitran devinfo_acpi_get_prober
504035Sphitran };
514035Sphitran
526573Sphitran DevinfoDevHandler devinfo_power_button_handler = {
536573Sphitran devinfo_power_button_add,
546573Sphitran NULL,
556573Sphitran NULL,
566573Sphitran NULL,
576573Sphitran NULL,
586573Sphitran NULL
596573Sphitran };
606573Sphitran
614035Sphitran static HalDevice *
devinfo_acpi_add(HalDevice * parent,di_node_t node,char * devfs_path,char * device_type)624035Sphitran devinfo_acpi_add(HalDevice *parent, di_node_t node, char *devfs_path,
634035Sphitran char *device_type)
644035Sphitran {
654035Sphitran HalDevice *d, *computer;
664035Sphitran char *driver_name;
674035Sphitran di_devlink_handle_t devlink_hdl;
684035Sphitran int major;
694035Sphitran di_minor_t minor;
704035Sphitran dev_t dev;
714035Sphitran char *minor_path = NULL;
724035Sphitran char *devpath;
734035Sphitran
744035Sphitran driver_name = di_driver_name(node);
756573Sphitran if ((driver_name == NULL) || (strcmp(driver_name, "acpi_drv") != 0)) {
764035Sphitran return (NULL);
774035Sphitran }
784035Sphitran
794035Sphitran d = hal_device_new();
804035Sphitran
814035Sphitran if ((computer = hal_device_store_find(hald_get_gdl(),
824035Sphitran "/org/freedesktop/Hal/devices/computer")) ||
834035Sphitran (computer = hal_device_store_find(hald_get_tdl(),
844035Sphitran "/org/freedesktop/Hal/devices/computer"))) {
854035Sphitran hal_device_property_set_string(computer,
864035Sphitran "system.formfactor", "laptop");
877137Sphitran hal_device_property_set_string(computer,
887137Sphitran "power_management.type", "acpi");
894035Sphitran }
904035Sphitran devinfo_set_default_properties(d, parent, node, devfs_path);
917137Sphitran devinfo_add_enqueue(d, devfs_path, &devinfo_acpi_handler);
924035Sphitran
934035Sphitran major = di_driver_major(node);
944035Sphitran if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
954035Sphitran return (d);
964035Sphitran }
974035Sphitran minor = DI_MINOR_NIL;
984035Sphitran while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
994035Sphitran dev = di_minor_devt(minor);
1004035Sphitran if ((major != major(dev)) ||
1014035Sphitran (di_minor_type(minor) != DDM_MINOR) ||
1024035Sphitran (di_minor_spectype(minor) != S_IFCHR) ||
1034035Sphitran ((minor_path = di_devfs_minor_path(minor)) == NULL)) {
1044035Sphitran continue;
1054035Sphitran }
1064035Sphitran
1074035Sphitran if (hal_device_store_match_key_value_string(hald_get_gdl(),
1084035Sphitran "solaris.devfs_path", minor_path) == NULL) {
1097137Sphitran devinfo_acpi_add_minor(d, node, minor_path, dev);
1104035Sphitran }
1114035Sphitran
1124035Sphitran di_devfs_path_free(minor_path);
1134035Sphitran }
1144035Sphitran di_devlink_fini(&devlink_hdl);
1154035Sphitran
1164035Sphitran return (d);
1174035Sphitran }
1184035Sphitran
1194035Sphitran void
devinfo_acpi_add_minor(HalDevice * parent,di_node_t node,char * minor_path,dev_t dev)1207137Sphitran devinfo_acpi_add_minor(HalDevice *parent, di_node_t node, char *minor_path,
1214035Sphitran dev_t dev)
1224035Sphitran {
1234035Sphitran HalDevice *d;
1244035Sphitran
1254035Sphitran d = hal_device_new();
1264035Sphitran devinfo_set_default_properties(d, parent, node, minor_path);
1277137Sphitran devinfo_add_enqueue(d, minor_path, &devinfo_acpi_handler);
1284035Sphitran }
1294035Sphitran
1306573Sphitran static HalDevice *
devinfo_power_button_add(HalDevice * parent,di_node_t node,char * devfs_path,char * device_type)1316573Sphitran devinfo_power_button_add(HalDevice *parent, di_node_t node, char *devfs_path,
1326573Sphitran char *device_type)
1336573Sphitran {
1346573Sphitran HalDevice *d;
1356573Sphitran char *driver_name;
1366573Sphitran
1376573Sphitran driver_name = di_driver_name(node);
1386573Sphitran if ((driver_name == NULL) || (strcmp(driver_name, "power") != 0)) {
1396573Sphitran return (NULL);
1406573Sphitran }
1416573Sphitran
1426573Sphitran d = hal_device_new();
1436573Sphitran
1446573Sphitran devinfo_set_default_properties(d, parent, node, devfs_path);
1456573Sphitran hal_device_add_capability(d, "button");
1466573Sphitran hal_device_property_set_bool(d, "button.has_state", FALSE);
1476573Sphitran hal_device_property_set_string(d, "info.category", "input");
1486573Sphitran hal_device_property_set_string(d, "button.type", "power");
1496573Sphitran hal_device_property_set_string(d, "info.product", "Power Button");
1506573Sphitran
1516573Sphitran devinfo_add_enqueue(d, devfs_path, &devinfo_power_button_handler);
1526573Sphitran
1536573Sphitran return (d);
1546573Sphitran }
1556573Sphitran
1566573Sphitran void
devinfo_power_button_event(void)157*7651SPhi.Tran@Sun.COM devinfo_power_button_event(void)
1586573Sphitran {
1596573Sphitran HalDevice *d = NULL;
1606573Sphitran HalDeviceStore *store = hald_get_gdl();
1616573Sphitran
1626573Sphitran d = hal_device_store_match_key_value_string (store, "button.type",
1636573Sphitran "power");
1646573Sphitran if (d != NULL) {
1656573Sphitran device_send_signal_condition(d, "ButtonPressed", "power");
1666573Sphitran }
1676573Sphitran }
1686573Sphitran
1696573Sphitran void
devinfo_brightness_hotkeys_event(char * subclass)170*7651SPhi.Tran@Sun.COM devinfo_brightness_hotkeys_event(char *subclass)
1716573Sphitran {
1726573Sphitran HalDevice *d = NULL;
1736573Sphitran
1746573Sphitran if ((d = hal_device_store_find(hald_get_gdl(),
1756573Sphitran "/org/freedesktop/Hal/devices/computer")) ||
1766573Sphitran (d = hal_device_store_find(hald_get_tdl(),
1776573Sphitran "/org/freedesktop/Hal/devices/computer"))) {
1786573Sphitran if (strcmp(subclass, ESC_PWRCTL_BRIGHTNESS_UP) == 0) {
1796573Sphitran device_send_signal_condition(d, "ButtonPressed",
1806573Sphitran "brightness-up");
1816573Sphitran } else {
1826573Sphitran device_send_signal_condition(d, "ButtonPressed",
1836573Sphitran "brightness-down");
1846573Sphitran }
185*7651SPhi.Tran@Sun.COM }
1866573Sphitran }
1876573Sphitran
1884035Sphitran void
devinfo_battery_rescan(char * parent_devfs_path,gchar * udi)189*7651SPhi.Tran@Sun.COM devinfo_battery_rescan(char *parent_devfs_path, gchar *udi)
1904035Sphitran {
1914035Sphitran HalDevice *d = NULL;
1924035Sphitran
1934035Sphitran d = hal_device_store_find(hald_get_gdl(), udi);
1944035Sphitran if (d == NULL) {
1954035Sphitran HAL_INFO(("device not found %s", udi));
1964035Sphitran return;
1974035Sphitran }
1984035Sphitran
1996573Sphitran hald_runner_run(d, "hald-probe-acpi", NULL,
200*7651SPhi.Tran@Sun.COM DEVINFO_PROBE_ACPI_TIMEOUT, devinfo_battery_rescan_probing_done,
2014035Sphitran NULL, NULL);
2024035Sphitran }
2034035Sphitran
2046573Sphitran void
devinfo_lid_event(char * subclass,gchar * udi)205*7651SPhi.Tran@Sun.COM devinfo_lid_event(char *subclass, gchar *udi)
2066573Sphitran {
2076573Sphitran HalDevice *d = NULL;
2086573Sphitran
2096573Sphitran d = hal_device_store_find(hald_get_gdl(), udi);
2106573Sphitran if (d == NULL) {
2116573Sphitran HAL_INFO(("device not found %s", udi));
2126573Sphitran return;
2136573Sphitran }
2146573Sphitran
2156573Sphitran hal_device_property_set_bool(d, "button.state.value",
216*7651SPhi.Tran@Sun.COM (strcmp(subclass, ESC_PWRCTL_REMOVE) == 0));
2176573Sphitran device_send_signal_condition(d, "ButtonPressed", "lid");
2186573Sphitran }
2196573Sphitran
220*7651SPhi.Tran@Sun.COM gboolean
devinfo_lid_rescan(HalDevice * d)221*7651SPhi.Tran@Sun.COM devinfo_lid_rescan(HalDevice *d)
222*7651SPhi.Tran@Sun.COM {
223*7651SPhi.Tran@Sun.COM if (hal_device_property_get_bool(d, "button.workaround")) {
224*7651SPhi.Tran@Sun.COM /* Set lid state to open for workaround */
225*7651SPhi.Tran@Sun.COM hal_device_property_set_bool(d, "button.state.value", FALSE);
226*7651SPhi.Tran@Sun.COM } else {
227*7651SPhi.Tran@Sun.COM hald_runner_run(d, "hald-probe-acpi", NULL,
228*7651SPhi.Tran@Sun.COM DEVINFO_PROBE_ACPI_TIMEOUT,
229*7651SPhi.Tran@Sun.COM devinfo_battery_rescan_probing_done, NULL, NULL);
230*7651SPhi.Tran@Sun.COM }
231*7651SPhi.Tran@Sun.COM
232*7651SPhi.Tran@Sun.COM return (TRUE);
233*7651SPhi.Tran@Sun.COM }
234*7651SPhi.Tran@Sun.COM
2354035Sphitran static void
devinfo_battery_rescan_probing_done(HalDevice * d,guint32 exit_type,gint return_code,char ** error,gpointer userdata1,gpointer userdata2)2364035Sphitran devinfo_battery_rescan_probing_done(HalDevice *d, guint32 exit_type,
2374035Sphitran gint return_code, char **error, gpointer userdata1, gpointer userdata2)
2384035Sphitran {
2394035Sphitran /* hald_runner_run() requires this function since cannot pass NULL */
2404035Sphitran }
2414035Sphitran
2424035Sphitran const gchar *
devinfo_acpi_get_prober(HalDevice * d,int * timeout)2437137Sphitran devinfo_acpi_get_prober(HalDevice *d, int *timeout)
2444035Sphitran {
245*7651SPhi.Tran@Sun.COM *timeout = DEVINFO_PROBE_ACPI_TIMEOUT; /* 30 second timeout */
2466573Sphitran return ("hald-probe-acpi");
2474035Sphitran }
248