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 * 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 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 * 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 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 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 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 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 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 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 * 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