4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 #include <sys/types.h>
28 #include <sys/mount.h>
31 #include "dd-deviced.h"
33 #include "device-notifier.h"
34 #include "device-handler.h"
35 #include "device-node.h"
36 #include "display/poll.h"
38 #include "hall/hall-handler.h"
43 #include "proc/proc-handler.h"
44 #include "edbus-handler.h"
46 #include "power-supply.h"
47 #include "display/setting.h"
48 #include "display/core.h"
49 #include "usb/usb-client.h"
51 #define PREDEF_DEVICE_CHANGED "device_changed"
52 #define PREDEF_POWER_CHANGED POWER_SUBSYSTEM
53 #define PREDEF_UDEV_CONTROL UDEV
55 #define TVOUT_X_BIN "/usr/bin/xberc"
56 #define TVOUT_FLAG 0x00000001
58 #define MOVINAND_MOUNT_POINT "/opt/media"
60 #define SYS_CLASS_INPUT "/sys/class/input"
62 #define USB_STATE_PLATFORM_PATH "/sys/devices/platform/jack/usb_online"
63 #define USB_STATE_SWITCH_PATH "/sys/devices/virtual/switch/usb_cable/state"
65 #define HDMI_NOT_SUPPORTED (-1)
66 #ifdef ENABLE_EDBUS_USE
68 static E_DBus_Connection *conn;
69 #endif /* ENABLE_EDBUS_USE */
79 SND_JACK_HEADPHONE = 0x0001,
80 SND_JACK_MICROPHONE = 0x0002,
81 SND_JACK_HEADSET = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
82 SND_JACK_LINEOUT = 0x0004,
83 SND_JACK_MECHANICAL = 0x0008, /* If detected separately */
84 SND_JACK_VIDEOOUT = 0x0010,
85 SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT,
88 #define CRADLE_APP_NAME "com.samsung.desk-dock"
89 #define VIRTUAL_CONTROLLER_APP_NAME "com.samsung.virtual-controller"
91 #define CHANGE_ACTION "change"
92 #define ENV_FILTER "CHGDET"
93 #define USB_NAME "usb"
94 #define USB_NAME_LEN 3
96 #define CHARGER_NAME "charger"
97 #define CHARGER_NAME_LEN 7
99 #define EARJACK_NAME "earjack"
100 #define EARJACK_NAME_LEN 7
102 #define EARKEY_NAME "earkey"
103 #define EARKEY_NAME_LEN 6
105 #define TVOUT_NAME "tvout"
106 #define TVOUT_NAME_LEN 5
108 #define HDMI_NAME "hdmi"
109 #define HDMI_NAME_LEN 4
111 #define HDCP_NAME "hdcp"
112 #define HDCP_NAME_LEN 4
114 #define HDMI_AUDIO_NAME "ch_hdmi_audio"
115 #define HDMI_AUDIO_LEN 13
117 #define CRADLE_NAME "cradle"
118 #define CRADLE_NAME_LEN 6
120 #define KEYBOARD_NAME "keyboard"
121 #define KEYBOARD_NAME_LEN 8
123 #define POWER_SUPPLY_NAME_LEN 12
125 #define CHARGE_NAME_LEN 17
126 #define BATTERY_NAME "battery"
127 #define BATTERY_NAME_LEN 7
128 #define CHARGEFULL_NAME "Full"
129 #define CHARGEFULL_NAME_LEN 4
130 #define CHARGENOW_NAME "Charging"
131 #define CHARGENOW_NAME_LEN 8
132 #define DISCHARGE_NAME "Discharging"
133 #define DISCHARGE_NAME_LEN 11
134 #define NOTCHARGE_NAME "Not charging"
135 #define NOTCHARGE_NAME_LEN 12
136 #define OVERHEAT_NAME "Overheat"
137 #define OVERHEAT_NAME_LEN 8
138 #define TEMPCOLD_NAME "Cold"
139 #define TEMPCOLD_NAME_LEN 4
140 #define OVERVOLT_NAME "Over voltage"
141 #define OVERVOLT_NAME_LEN 12
143 #define SWITCH_DEVICE_USB "usb_cable"
145 #define LAUNCH_APP "launch-app"
146 #define DESK_DOCK "desk-dock"
148 /* Ticker notification */
149 #define DOCK_CONNECTED "dock-connected"
150 #define HDMI_CONNECTED "hdmi-connected"
151 #define HDMI_DISCONNECTED "hdmi-disconnected"
153 #define METHOD_GET_HDMI "GetHDMI"
154 #define METHOD_GET_HDCP "GetHDCP"
155 #define METHOD_GET_HDMI_AUDIO "GetHDMIAudio"
156 #define SIGNAL_HDMI_STATE "ChangedHDMI"
157 #define SIGNAL_HDCP_STATE "ChangedHDCP"
158 #define SIGNAL_HDMI_AUDIO_STATE "ChangedHDMIAudio"
160 #define METHOD_FACTORY_MODE "factorymode"
161 #define VCONFKEY_SYSMAN_FACTORY_MODE "memory/sysman/factory_mode"
163 #define HDCP_HDMI_VALUE(HDCP, HDMI) ((HDCP << 1) | HDMI)
165 #define METHOD_GET_CRADLE "GetCradle"
166 #define SIGNAL_CRADLE_STATE "ChangedCradle"
184 static int ss_flags = 0;
186 static int input_device_number;
189 static struct udev *udev = NULL;
191 static struct udev_monitor *mon = NULL;
192 static Ecore_Fd_Handler *ufdh = NULL;
195 static struct udev_monitor *mon_udev = NULL;
196 static Ecore_Fd_Handler *ufdh_udev = NULL;
197 static int ufd_udev = -1;
199 static dd_list *opt_uevent_list = NULL;
200 static dd_list *opt_kernel_uevent_list = NULL;
201 static int hdmi_status = 0;
203 static int factory_mode = 0;
205 enum udev_subsystem_type {
214 static const struct udev_subsystem {
215 const enum udev_subsystem_type type;
218 } udev_subsystems[] = {
219 { UDEV_HALL_IC, HALL_IC_SUBSYSTEM, NULL},
220 { UDEV_INPUT, INPUT_SUBSYSTEM, NULL },
221 { UDEV_LCD_EVENT, LCD_EVENT_SUBSYSTEM, NULL },
222 { UDEV_PLATFORM, PLATFORM_SUBSYSTEM, NULL },
223 { UDEV_POWER, POWER_SUBSYSTEM, NULL},
224 { UDEV_SWITCH, SWITCH_SUBSYSTEM, NULL },
227 static struct extcon_device {
228 const enum extcon_type type;
232 } extcon_devices[] = {
233 { EXTCON_TA, "/csa/factory/batt_cable_count", 0, 0},
234 { EXTCON_EARJACK, "/csa/factory/earjack_count", 0, 0},
237 extern int battery_power_off_act(void *data);
238 extern int battery_charge_err_act(void *data);
240 int extcon_set_count(int index)
246 extcon_devices[index].count++;
248 if (extcon_devices[index].fd < 0) {
249 _E("cannot open file(%s)", extcon_devices[index].str);
252 lseek(extcon_devices[index].fd, 0, SEEK_SET);
253 _I("ext(%d) count %d", index, extcon_devices[index].count);
254 snprintf(buf, sizeof(buf), "%d", extcon_devices[index].count);
256 r = write(extcon_devices[index].fd, buf, strlen(buf));
262 static int extcon_get_count(int index)
269 fd = open(extcon_devices[index].str, O_RDWR);
273 r = read(fd, buf, BUFF_MAX);
274 if ((r >= 0) && (r < BUFF_MAX))
283 extcon_devices[index].fd = fd;
284 extcon_devices[index].count = atoi(buf);
285 _I("get extcon(%d:%x) count %d",
286 index, extcon_devices[index].fd, extcon_devices[index].count);
291 static int extcon_create_count(int index)
297 fd = open(extcon_devices[index].str, O_RDWR | O_CREAT, 0644);
299 _E("cannot open file(%s)", extcon_devices[index].str);
302 snprintf(buf, sizeof(buf), "%d", extcon_devices[index].count);
303 r = write(fd, buf, strlen(buf));
309 _E("cannot write file(%s)", extcon_devices[index].str);
312 extcon_devices[index].fd = fd;
313 _I("create extcon(%d:%x) %s",
314 index, extcon_devices[index].fd, extcon_devices[index].str);
318 static int extcon_count_init(void)
322 for (i = 0; i < ARRAY_SIZE(extcon_devices); i++) {
323 if (extcon_get_count(i) >= 0)
325 ret = extcon_create_count(i);
332 int get_usb_state_direct(void)
339 if (access(USB_STATE_PLATFORM_PATH, F_OK) == 0)
340 path = USB_STATE_PLATFORM_PATH;
341 else if (access(USB_STATE_SWITCH_PATH, F_OK) == 0)
342 path = USB_STATE_SWITCH_PATH;
344 _E("Cannot get direct path");
348 fp = fopen(path, "r");
350 _E("Cannot open jack node");
354 if (!fgets(str, sizeof(str), fp)) {
355 _E("cannot get string from jack node");
365 static void usb_chgdet_cb(void *data)
369 char params[BUFF_MAX];
372 ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &val);
377 val = get_usb_state_direct();
379 _I("jack - usb changed %d",val);
380 check_lowbat_charge_device(val);
382 battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
383 _D("usb device notification");
385 usb_state_changed(val);
387 _E("fail to get usb_online status");
391 static void show_ticker_notification(char *text, int queue)
393 struct ticker_data t_data;
394 static const struct device_ops *ticker = NULL;
396 FIND_DEVICE_VOID(ticker, "ticker");
400 ticker->init(&t_data);
403 static void launch_cradle(int val)
405 struct popup_data *params;
406 static const struct device_ops *apps = NULL;
408 FIND_DEVICE_VOID(apps, "apps");
410 params = malloc(sizeof(struct popup_data));
411 if (params == NULL) {
415 params->name = LAUNCH_APP;
416 params->key = DESK_DOCK;
417 _I("%s %s %x", params->name, params->key, params);
420 apps->exit((void *)params);
422 show_ticker_notification(DOCK_CONNECTED, 0);
424 apps->init((void *)params);
430 static int display_changed(void *data)
432 enum state_t state = (enum state_t)data;
435 if (battery.charge_now == CHARGER_ABNORMAL && battery.health == HEALTH_BAD) {
436 pm_lock_internal(INTERNAL_LOCK_POPUP, LCD_DIM, STAY_CUR_STATE, 0);
440 if (state != S_NORMAL)
443 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
444 if (ret >= 0 && cradle == DOCK_SOUND) {
445 pm_lock_internal(getpid(), LCD_DIM, STAY_CUR_STATE, 0);
446 _I("sound dock is connected! dim lock is on.");
449 pm_lock_internal(getpid(), LCD_DIM, STAY_CUR_STATE, 0);
450 _I("hdmi is connected! dim lock is on.");
455 static void cradle_send_broadcast(int status)
464 _I("broadcast cradle status %d", status);
466 snprintf(str_status, sizeof(str_status), "%d", status);
469 broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
470 SIGNAL_CRADLE_STATE, "i", arr);
473 static int cradle_cb(void *data)
488 cradle_send_broadcast(old);
492 static void cradle_chgdet_cb(void *data)
497 pm_change_internal(getpid(), LCD_NORMAL);
502 ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_CRADLE_ONLINE, &val);
504 _E("failed to get status");
509 _I("jack - cradle changed %d", val);
510 cradle_cb((void *)&val);
511 if (vconf_set_int(VCONFKEY_SYSMAN_CRADLE_STATUS, val) != 0) {
512 _E("failed to set vconf status");
516 if (val == DOCK_SOUND)
517 pm_lock_internal(getpid(), LCD_DIM, STAY_CUR_STATE, 0);
518 else if (val == DOCK_NONE)
519 pm_unlock_internal(getpid(), LCD_DIM, PM_SLEEP_MARGIN);
524 void sync_cradle_status(void)
528 if ((device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_CRADLE_ONLINE, &val) != 0) ||
529 vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &status) != 0)
531 if ((val != 0 && status == 0) || (val == 0 && status != 0))
532 cradle_chgdet_cb(NULL);
535 static void earkey_chgdet_cb(void *data)
543 ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARKEY_ONLINE, &val);
545 _E("failed to get status");
549 _I("jack - earkey changed %d", val);
550 vconf_set_int(VCONFKEY_SYSMAN_EARJACKKEY, val);
553 static void tvout_chgdet_cb(void *data)
555 _I("jack - tvout changed");
556 pm_change_internal(getpid(), LCD_NORMAL);
559 static void hdcp_hdmi_send_broadcast(int status)
568 _I("broadcast hdmi status %d", status);
570 snprintf(str_status, sizeof(str_status), "%d", status);
573 broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
574 SIGNAL_HDMI_STATE, "i", arr);
577 static int hdcp_hdmi_cb(void *data)
587 val = HDCP_HDMI_VALUE(val, hdmi_status);
593 hdcp_hdmi_send_broadcast(old);
597 static int hdmi_cec_execute(void *data)
599 static const struct device_ops *ops = NULL;
601 FIND_DEVICE_INT(ops, "hdmi-cec");
603 return ops->execute(data);
606 static void hdmi_chgdet_cb(void *data)
611 pm_change_internal(getpid(), LCD_NORMAL);
612 if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_HDMI_SUPPORT, &val) == 0) {
614 _I("target is not support HDMI");
615 vconf_set_int(VCONFKEY_SYSMAN_HDMI, HDMI_NOT_SUPPORTED);
623 ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_HDMI_ONLINE, &val);
625 _E("failed to get status");
630 _I("jack - hdmi changed %d", val);
631 vconf_set_int(VCONFKEY_SYSMAN_HDMI, val);
633 device_notify(DEVICE_NOTIFIER_HDMI, (void *)val);
636 pm_lock_internal(INTERNAL_LOCK_HDMI, LCD_DIM, STAY_CUR_STATE, 0);
637 show_ticker_notification(HDMI_CONNECTED, 0);
639 show_ticker_notification(HDMI_DISCONNECTED, 0);
640 pm_unlock_internal(INTERNAL_LOCK_HDMI, LCD_DIM, PM_SLEEP_MARGIN);
642 hdmi_cec_execute((void *)val);
645 static void hdcp_send_broadcast(int status)
654 _D("broadcast hdcp status %d", status);
656 snprintf(str_status, sizeof(str_status), "%d", status);
659 broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
660 SIGNAL_HDCP_STATE, "i", arr);
663 static int hdcp_chgdet_cb(void *data)
676 hdcp_send_broadcast(old);
680 static void hdmi_audio_send_broadcast(int status)
689 _D("broadcast hdmi audio status %d", status);
691 snprintf(str_status, sizeof(str_status), "%d", status);
694 broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
695 SIGNAL_HDMI_AUDIO_STATE, "i", arr);
698 static int hdmi_audio_chgdet_cb(void *data)
711 hdmi_audio_send_broadcast(old);
715 static void keyboard_chgdet_cb(void *data)
723 ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_KEYBOARD_ONLINE, &val);
725 _E("failed to get status");
726 vconf_set_int(VCONFKEY_SYSMAN_SLIDING_KEYBOARD, VCONFKEY_SYSMAN_SLIDING_KEYBOARD_NOT_SUPPORTED);
730 _I("jack - keyboard changed %d", val);
733 vconf_set_int(VCONFKEY_SYSMAN_SLIDING_KEYBOARD, val);
736 static void ums_unmount_cb(void *data)
738 umount(MOVINAND_MOUNT_POINT);
741 #ifdef ENABLE_EDBUS_USE
742 static void cb_xxxxx_signaled(void *data, DBusMessage * msg)
747 dbus_error_init(&err);
748 if (dbus_message_get_args
749 (msg, &err, DBUS_TYPE_STRING, &args, DBUS_TYPE_INVALID)) {
750 if (!strcmp(args, "action")) ; /* action */
755 #endif /* ENABLE_EDBUS_USE */
757 static void check_capacity_status(const char *env_value)
759 if (env_value == NULL)
761 battery.capacity = atoi(env_value);
764 static void check_charge_status(const char *env_value)
766 if (env_value == NULL)
768 if (strncmp(env_value, CHARGEFULL_NAME , CHARGEFULL_NAME_LEN) == 0) {
769 battery.charge_full = CHARGING_FULL;
770 battery.charge_now = CHARGER_DISCHARGING;
771 } else if (strncmp(env_value, CHARGENOW_NAME, CHARGENOW_NAME_LEN) == 0) {
772 battery.charge_full = CHARGING_NOT_FULL;
773 battery.charge_now = CHARGER_CHARGING;
774 } else if (strncmp(env_value, DISCHARGE_NAME, DISCHARGE_NAME_LEN) == 0) {
775 battery.charge_full = CHARGING_NOT_FULL;
776 battery.charge_now = CHARGER_DISCHARGING;
777 } else if (strncmp(env_value, NOTCHARGE_NAME, NOTCHARGE_NAME_LEN) == 0) {
778 battery.charge_full = CHARGING_NOT_FULL;
779 battery.charge_now = CHARGER_ABNORMAL;
781 battery.charge_full = CHARGING_NOT_FULL;
782 battery.charge_now = CHARGER_DISCHARGING;
786 static void check_health_status(const char *env_value)
788 if (env_value == NULL) {
789 battery.health = HEALTH_GOOD;
790 battery.temp = TEMP_LOW;
791 battery.ovp = OVP_NORMAL;
794 if (strncmp(env_value, OVERHEAT_NAME, OVERHEAT_NAME_LEN) == 0) {
795 battery.health = HEALTH_BAD;
796 battery.temp = TEMP_HIGH;
797 battery.ovp = OVP_NORMAL;
798 } else if (strncmp(env_value, TEMPCOLD_NAME, TEMPCOLD_NAME_LEN) == 0) {
799 battery.health = HEALTH_BAD;
800 battery.temp = TEMP_LOW;
801 battery.ovp = OVP_NORMAL;
802 } else if (strncmp(env_value, OVERVOLT_NAME, OVERVOLT_NAME_LEN) == 0) {
803 battery.health = HEALTH_GOOD;
804 battery.temp = TEMP_LOW;
805 battery.ovp = OVP_ABNORMAL;
807 battery.health = HEALTH_GOOD;
808 battery.temp = TEMP_LOW;
809 battery.ovp = OVP_NORMAL;
813 static void check_online_status(const char *env_value)
815 if (env_value == NULL)
817 battery.online = atoi(env_value);
820 static void check_present_status(const char *env_value)
822 if (env_value == NULL) {
823 battery.present = PRESENT_NORMAL;
826 battery.present = atoi(env_value);
829 static int earjack_execute(void *data)
831 static const struct device_ops *ops = NULL;
833 FIND_DEVICE_INT(ops, "earjack");
835 return ops->execute(data);
838 static int hall_ic_execute(void)
840 static const struct device_ops *ops = NULL;
842 FIND_DEVICE_INT(ops, HALL_IC_NAME);
844 return ops->execute(NULL);
847 static int siop_execute(const char *siop, const char *rear)
849 static const struct device_ops *ops = NULL;
850 struct siop_data params;
852 FIND_DEVICE_INT(ops, PROC_OPS_NAME);
857 params.siop = atoi(siop);
861 params.rear = atoi(rear);
862 return ops->execute((void *)¶ms);
865 static int changed_device(const char *name, const char *value)
879 if (strncmp(name, USB_NAME, USB_NAME_LEN) == 0)
880 usb_chgdet_cb((void *)state);
881 else if (strncmp(name, EARJACK_NAME, EARJACK_NAME_LEN) == 0)
882 earjack_execute((void *)state);
883 else if (strncmp(name, EARKEY_NAME, EARKEY_NAME_LEN) == 0)
884 earkey_chgdet_cb((void *)state);
885 else if (strncmp(name, TVOUT_NAME, TVOUT_NAME_LEN) == 0)
886 tvout_chgdet_cb((void *)state);
887 else if (strncmp(name, HDMI_NAME, HDMI_NAME_LEN) == 0)
888 hdmi_chgdet_cb((void *)state);
889 else if (strncmp(name, HDCP_NAME, HDCP_NAME_LEN) == 0) {
890 hdcp_chgdet_cb((void *)state);
891 hdcp_hdmi_cb((void *)state);
893 else if (strncmp(name, HDMI_AUDIO_NAME, HDMI_AUDIO_LEN) == 0)
894 hdmi_audio_chgdet_cb((void *)state);
895 else if (strncmp(name, CRADLE_NAME, CRADLE_NAME_LEN) == 0)
896 cradle_chgdet_cb((void *)state);
897 else if (strncmp(name, KEYBOARD_NAME, KEYBOARD_NAME_LEN) == 0)
898 keyboard_chgdet_cb((void *)state);
899 else if (strncmp(name, POWER_SUBSYSTEM, POWER_SUPPLY_NAME_LEN) == 0)
900 power_supply((void *)state);
905 static int booting_done(void *data)
919 power_supply_timer_stop();
920 power_supply_init(NULL);
922 /* set initial state for devices */
923 input_device_number = 0;
924 cradle_chgdet_cb(NULL);
925 keyboard_chgdet_cb(NULL);
926 hdmi_chgdet_cb(NULL);
928 ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &val);
929 if (ret == 0 && val != 0)
934 static Eina_Bool uevent_kernel_control_cb(void *data, Ecore_Fd_Handler *fd_handler)
936 struct udev_device *dev = NULL;
937 struct udev_list_entry *list_entry = NULL;
938 const char *subsystem = NULL;
939 const char *env_name = NULL;
940 const char *env_value = NULL;
944 const char *siop_level;
945 const char *rear_level;
948 struct uevent_handler *uh;
952 if ((dev = udev_monitor_receive_device(mon)) == NULL)
955 subsystem = udev_device_get_subsystem(dev);
957 for (i = 0; i < ARRAY_SIZE(udev_subsystems); i++) {
958 len = strlen(udev_subsystems[i].str);
959 if (!strncmp(subsystem, udev_subsystems[i].str, len))
963 if (i >= ARRAY_SIZE(udev_subsystems))
966 devpath = udev_device_get_devpath(dev);
968 switch (udev_subsystems[i].type) {
970 if (!strncmp(devpath, HALL_IC_PATH, strlen(HALL_IC_PATH))) {
976 /* check new input device */
977 if (!fnmatch(INPUT_PATH, devpath, 0)) {
978 action = udev_device_get_action(dev);
979 devnode = udev_device_get_devnode(dev);
980 if (!strcmp(action, UDEV_ADD))
981 device_notify(DEVICE_NOTIFIER_INPUT_ADD, (void *)devnode);
982 else if (!strcmp(action, UDEV_REMOVE))
983 device_notify(DEVICE_NOTIFIER_INPUT_REMOVE, (void *)devnode);
988 /* check new esd device */
989 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
990 action = udev_device_get_action(dev);
991 if (!strcmp(action, UDEV_CHANGE))
992 device_notify(DEVICE_NOTIFIER_LCD_ESD, "ESD");
997 env_name = udev_device_get_property_value(dev, "SWITCH_NAME");
998 env_value = udev_device_get_property_value(dev, "SWITCH_STATE");
999 changed_device(env_name, env_value);
1002 if (!fnmatch(THERMISTOR_PATH, devpath, 0)) {
1003 siop_level = udev_device_get_property_value(dev, "TEMPERATURE");
1004 rear_level = udev_device_get_property_value(dev, "REAR_TEMPERATURE");
1005 siop_execute(siop_level, rear_level);
1009 env_value = udev_device_get_property_value(dev, ENV_FILTER);
1012 changed_device(env_value, NULL);
1015 udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(dev)) {
1016 env_name = udev_list_entry_get_name(list_entry);
1017 if (env_name == NULL)
1019 if (strncmp(env_name, CHARGE_NAME, CHARGE_NAME_LEN) == 0) {
1020 env_value = udev_list_entry_get_value(list_entry);
1021 if (env_value == NULL)
1023 if (strncmp(env_value, BATTERY_NAME, BATTERY_NAME_LEN) == 0) {
1031 env_value = udev_device_get_property_value(dev, CHARGE_STATUS);
1032 check_charge_status(env_value);
1033 env_value = udev_device_get_property_value(dev, CHARGE_ONLINE);
1034 check_online_status(env_value);
1035 env_value = udev_device_get_property_value(dev, CHARGE_HEALTH);
1036 check_health_status(env_value);
1037 env_value = udev_device_get_property_value(dev, CHARGE_PRESENT);
1038 check_present_status(env_value);
1039 env_value = udev_device_get_property_value(dev, CAPACITY);
1040 check_capacity_status(env_value);
1041 ret = booting_done(NULL);
1043 battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
1045 changed_device(subsystem, env_value);
1047 changed_device(subsystem, NULL);
1052 DD_LIST_FOREACH(opt_kernel_uevent_list, l, l_data) {
1053 uh = (struct uevent_handler *)l_data;
1054 if (strncmp(subsystem, uh->subsystem, strlen(uh->subsystem)))
1056 uh->uevent_func(dev);
1059 udev_device_unref(dev);
1063 static Eina_Bool uevent_udev_control_cb(void *data, Ecore_Fd_Handler *fd_handler)
1065 struct udev_device *dev = NULL;
1068 struct uevent_handler *uh;
1069 const char *subsystem = NULL;
1071 dev = udev_monitor_receive_device(mon_udev);
1075 subsystem = udev_device_get_subsystem(dev);
1077 _E("Failed to get subsystem from uevent");
1081 DD_LIST_FOREACH(opt_uevent_list, l, l_data) {
1082 uh = (struct uevent_handler *)l_data;
1083 if (strncmp(subsystem, uh->subsystem, strlen(uh->subsystem)))
1085 uh->uevent_func(dev);
1089 udev_device_unref(dev);
1093 static int uevent_kernel_control_stop(void)
1095 struct udev_device *dev = NULL;
1098 ecore_main_fd_handler_del(ufdh);
1106 dev = udev_monitor_receive_device(mon);
1108 udev_device_unref(dev);
1111 udev_monitor_unref(mon);
1114 if (udev && !mon_udev) {
1121 static int uevent_udev_control_stop(void)
1123 struct udev_device *dev = NULL;
1126 ecore_main_fd_handler_del(ufdh_udev);
1129 if (ufd_udev >= 0) {
1134 dev = udev_monitor_receive_device(mon_udev);
1136 udev_device_unref(dev);
1139 udev_monitor_unref(mon_udev);
1149 static int uevent_kernel_control_start(void)
1154 _E("uevent control routine is alreay started");
1161 _E("error create udev");
1166 mon = udev_monitor_new_from_netlink(udev, UDEV);
1168 _E("error udev_monitor create");
1172 if (udev_monitor_set_receive_buffer_size(mon, UDEV_MONITOR_SIZE) != 0) {
1173 _E("fail to set receive buffer size");
1177 for (i = 0; i < ARRAY_SIZE(udev_subsystems); i++) {
1178 ret = udev_monitor_filter_add_match_subsystem_devtype(mon,
1179 udev_subsystems[i].str, udev_subsystems[i].devtype);
1181 _E("error apply subsystem filter");
1186 ret = udev_monitor_filter_update(mon);
1188 _E("error udev_monitor_filter_update");
1190 ufd = udev_monitor_get_fd(mon);
1192 _E("error udev_monitor_get_fd");
1196 ufdh = ecore_main_fd_handler_add(ufd, ECORE_FD_READ,
1197 uevent_kernel_control_cb, NULL, NULL, NULL);
1199 _E("error ecore_main_fd_handler_add");
1203 if (udev_monitor_enable_receiving(mon) < 0) {
1204 _E("error unable to subscribe to udev events");
1210 uevent_kernel_control_stop();
1215 static int uevent_udev_control_start(void)
1219 if (udev && mon_udev) {
1220 _E("uevent control routine is alreay started");
1227 _E("error create udev");
1232 mon_udev = udev_monitor_new_from_netlink(udev, "udev");
1233 if (mon_udev == NULL) {
1234 _E("error udev_monitor create");
1238 if (udev_monitor_set_receive_buffer_size(mon_udev, UDEV_MONITOR_SIZE_LARGE) != 0) {
1239 _E("fail to set receive buffer size");
1243 ufd_udev = udev_monitor_get_fd(mon_udev);
1244 if (ufd_udev == -1) {
1245 _E("error udev_monitor_get_fd");
1249 ufdh_udev = ecore_main_fd_handler_add(ufd_udev, ECORE_FD_READ,
1250 uevent_udev_control_cb, NULL, NULL, NULL);
1252 _E("error ecore_main_fd_handler_add");
1256 if (udev_monitor_enable_receiving(mon_udev) < 0) {
1257 _E("error unable to subscribe to udev events");
1263 uevent_udev_control_stop();
1267 int register_uevent_control(const struct uevent_handler *uh)
1274 ret = udev_monitor_filter_add_match_subsystem_devtype(mon_udev,
1275 uh->subsystem, NULL);
1277 _E("FAIL: udev_monitor_filter_add_match_subsystem_devtype()");
1281 ret = udev_monitor_filter_update(mon_udev);
1283 _E("error udev_monitor_filter_update");
1285 DD_LIST_APPEND(opt_uevent_list, uh);
1290 void unregister_uevent_control(const struct uevent_handler *uh)
1294 struct uevent_handler *handler;
1296 DD_LIST_FOREACH(opt_uevent_list, l, data) {
1297 handler = (struct uevent_handler *)data;
1298 if (strncmp(handler->subsystem, uh->subsystem, strlen(uh->subsystem)))
1300 if (handler->uevent_func != uh->uevent_func)
1303 DD_LIST_REMOVE(opt_uevent_list, handler);
1308 int register_kernel_uevent_control(const struct uevent_handler *uh)
1315 ret = udev_monitor_filter_add_match_subsystem_devtype(mon,
1316 uh->subsystem, NULL);
1318 _E("FAIL: udev_monitor_filter_add_match_subsystem_devtype()");
1322 ret = udev_monitor_filter_update(mon);
1324 _E("error udev_monitor_filter_update");
1326 DD_LIST_APPEND(opt_kernel_uevent_list, uh);
1331 void unregister_kernel_uevent_control(const struct uevent_handler *uh)
1335 struct uevent_handler *handler;
1337 DD_LIST_FOREACH(opt_kernel_uevent_list, l, data) {
1338 handler = (struct uevent_handler *)data;
1339 if (strncmp(handler->subsystem, uh->subsystem, strlen(uh->subsystem)))
1341 if (handler->uevent_func != uh->uevent_func)
1344 DD_LIST_REMOVE(opt_kernel_uevent_list, data);
1349 int uevent_udev_get_path(const char *subsystem, dd_list **list)
1351 struct udev_enumerate *enumerate = NULL;
1352 struct udev_list_entry *devices, *dev_list_entry;
1358 _E("error create udev");
1363 enumerate = udev_enumerate_new(udev);
1367 ret = udev_enumerate_add_match_subsystem(enumerate, subsystem);
1371 ret = udev_enumerate_scan_devices(enumerate);
1375 devices = udev_enumerate_get_list_entry(enumerate);
1377 udev_list_entry_foreach(dev_list_entry, devices) {
1379 path = udev_list_entry_get_name(dev_list_entry);
1380 _D("subsystem : %s, path : %s", subsystem, path);
1381 DD_LIST_APPEND(*list, (void*)path);
1387 static DBusMessage *dbus_cradle_handler(E_DBus_Object *obj, DBusMessage *msg)
1389 DBusMessageIter iter;
1393 ret = cradle_cb(NULL);
1394 _I("cradle %d", ret);
1396 reply = dbus_message_new_method_return(msg);
1397 dbus_message_iter_init_append(reply, &iter);
1398 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1402 static DBusMessage *dbus_hdcp_hdmi_handler(E_DBus_Object *obj, DBusMessage *msg)
1404 DBusMessageIter iter;
1408 ret = hdcp_hdmi_cb(NULL);
1411 reply = dbus_message_new_method_return(msg);
1412 dbus_message_iter_init_append(reply, &iter);
1413 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1417 static DBusMessage *dbus_hdcp_handler(E_DBus_Object *obj, DBusMessage *msg)
1419 DBusMessageIter iter;
1423 ret = hdcp_chgdet_cb(NULL);
1426 reply = dbus_message_new_method_return(msg);
1427 dbus_message_iter_init_append(reply, &iter);
1428 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1432 static DBusMessage *dbus_hdmi_audio_handler(E_DBus_Object *obj, DBusMessage *msg)
1434 DBusMessageIter iter;
1438 ret = hdmi_audio_chgdet_cb(NULL);
1439 _I("hdmi audio %d", ret);
1441 reply = dbus_message_new_method_return(msg);
1442 dbus_message_iter_init_append(reply, &iter);
1443 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1447 static DBusMessage *dbus_device_handler(E_DBus_Object *obj, DBusMessage *msg)
1450 DBusMessageIter iter;
1458 dbus_error_init(&err);
1460 if (!dbus_message_get_args(msg, &err,
1461 DBUS_TYPE_STRING, &type_str,
1462 DBUS_TYPE_INT32, &argc,
1463 DBUS_TYPE_STRING, &argv[0],
1464 DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
1465 _E("there is no message");
1471 _E("message is invalid!");
1476 pid = get_edbus_sender_pid(msg);
1477 if (kill(pid, 0) == -1) {
1478 _E("%d process does not exist, dbus ignored!", pid);
1483 changed_device(argv[0], argv[1]);
1486 reply = dbus_message_new_method_return(msg);
1487 dbus_message_iter_init_append(reply, &iter);
1488 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1493 static DBusMessage *dbus_battery_handler(E_DBus_Object *obj, DBusMessage *msg)
1496 DBusMessageIter iter;
1504 dbus_error_init(&err);
1506 if (!dbus_message_get_args(msg, &err,
1507 DBUS_TYPE_STRING, &type_str,
1508 DBUS_TYPE_INT32, &argc,
1509 DBUS_TYPE_STRING, &argv[0],
1510 DBUS_TYPE_STRING, &argv[1],
1511 DBUS_TYPE_STRING, &argv[2],
1512 DBUS_TYPE_STRING, &argv[3],
1513 DBUS_TYPE_STRING, &argv[4], DBUS_TYPE_INVALID)) {
1514 _E("there is no message");
1520 _E("message is invalid!");
1525 pid = get_edbus_sender_pid(msg);
1526 if (kill(pid, 0) == -1) {
1527 _E("%d process does not exist, dbus ignored!", pid);
1531 check_capacity_status(argv[0]);
1532 check_charge_status(argv[1]);
1533 check_health_status(argv[2]);
1534 check_online_status(argv[3]);
1535 check_present_status(argv[4]);
1536 _I("%d %d %d %d %d %d %d %d",
1538 battery.charge_full,
1545 battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
1546 changed_device(POWER_SUBSYSTEM, argv[0]);
1548 reply = dbus_message_new_method_return(msg);
1549 dbus_message_iter_init_append(reply, &iter);
1550 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1555 static DBusMessage *dbus_udev_handler(E_DBus_Object *obj, DBusMessage *msg)
1558 DBusMessageIter iter;
1566 dbus_error_init(&err);
1568 if (!dbus_message_get_args(msg, &err,
1569 DBUS_TYPE_STRING, &type_str,
1570 DBUS_TYPE_INT32, &argc,
1571 DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
1572 _E("there is no message");
1578 _E("message is invalid!");
1583 pid = get_edbus_sender_pid(msg);
1584 if (kill(pid, 0) == -1) {
1585 _E("%d process does not exist, dbus ignored!", pid);
1590 if (strncmp(argv, "start", strlen("start")) == 0) {
1591 uevent_kernel_control_start();
1592 uevent_udev_control_start();
1593 } else if (strncmp(argv, "stop", strlen("stop")) == 0) {
1594 uevent_kernel_control_stop();
1595 uevent_udev_control_stop();
1599 reply = dbus_message_new_method_return(msg);
1600 dbus_message_iter_init_append(reply, &iter);
1601 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1606 int is_factory_mode(void)
1608 return factory_mode;
1611 void internal_pm_change_state(unsigned int s_bits)
1613 if (is_factory_mode() == 1)
1614 _D("skip LCD control for factory mode");
1616 pm_change_internal(getpid(), s_bits);
1619 static int set_factory_mode(int status)
1623 if (status == 1 || status == 0) {
1624 factory_mode = status;
1625 /* For USB-server to refer the value */
1626 ret = vconf_set_int(VCONFKEY_SYSMAN_FACTORY_MODE, status);
1628 _E("FAIL: vconf_set_int()");
1631 return factory_mode;
1634 static DBusMessage *dbus_factory_mode(E_DBus_Object *obj, DBusMessage *msg)
1637 DBusMessageIter iter;
1645 dbus_error_init(&err);
1647 if (!dbus_message_get_args(msg, &err,
1648 DBUS_TYPE_STRING, &type_str,
1649 DBUS_TYPE_INT32, &argc,
1650 DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
1651 _E("there is no message");
1657 _E("message is invalid!");
1662 pid = get_edbus_sender_pid(msg);
1663 if (kill(pid, 0) == -1) {
1664 _E("%d process does not exist, dbus ignored!", pid);
1669 ret = set_factory_mode(atoi(argv));
1671 reply = dbus_message_new_method_return(msg);
1672 dbus_message_iter_init_append(reply, &iter);
1673 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1678 static const struct edbus_method edbus_methods[] = {
1679 { PREDEF_DEVICE_CHANGED, "siss", "i", dbus_device_handler },
1680 { PREDEF_POWER_CHANGED, "sisssss", "i", dbus_battery_handler },
1681 { PREDEF_UDEV_CONTROL, "sis","i", dbus_udev_handler },
1682 { METHOD_GET_HDCP, NULL, "i", dbus_hdcp_handler },
1683 { METHOD_GET_HDMI_AUDIO, NULL, "i", dbus_hdmi_audio_handler },
1684 { METHOD_GET_HDMI, NULL, "i", dbus_hdcp_hdmi_handler },
1685 { METHOD_GET_CRADLE, NULL, "i", dbus_cradle_handler },
1686 { METHOD_FACTORY_MODE, "sis","i", dbus_factory_mode },
1689 static int device_change_poweroff(void *data)
1691 uevent_kernel_control_stop();
1692 uevent_udev_control_stop();
1696 static void device_change_init(void *data)
1700 power_supply_timer_start();
1701 if (extcon_count_init() != 0)
1702 _E("fail to init extcon files");
1703 register_notifier(DEVICE_NOTIFIER_POWEROFF, device_change_poweroff);
1704 register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
1705 register_notifier(DEVICE_NOTIFIER_LCD, display_changed);
1706 ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
1708 _E("fail to init edbus method(%d)", ret);
1710 /* dbus noti change cb */
1711 #ifdef ENABLE_EDBUS_USE
1713 conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
1715 _E("check system dbus running!\n");
1717 e_dbus_signal_handler_add(conn, NULL, "/system/uevent/xxxxx",
1718 "system.uevent.xxxxx",
1719 "Change", cb_xxxxx_signaled, data);
1720 #endif /* ENABLE_EDBUS_USE */
1721 if (uevent_kernel_control_start() != 0) {
1722 _E("fail uevent control init");
1726 if (uevent_udev_control_start() != 0) {
1727 _E("fail uevent control init");
1732 static void device_change_exit(void *data)
1735 unregister_notifier(DEVICE_NOTIFIER_POWEROFF, device_change_poweroff);
1736 unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
1737 unregister_notifier(DEVICE_NOTIFIER_LCD, display_changed);
1738 for (i = 0; i < ARRAY_SIZE(extcon_devices); i++) {
1739 if (extcon_devices[i].fd <= 0)
1741 close(extcon_devices[i].fd);
1746 static const struct device_ops change_device_ops = {
1747 .priority = DEVICE_PRIORITY_NORMAL,
1748 .name = "device change",
1749 .init = device_change_init,
1750 .exit = device_change_exit,
1753 DEVICE_OPS_REGISTER(&change_device_ops)