4 * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
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.
21 #include <hal/device/hal-touchscreen.h>
22 #include <libsyscommon/libgdbus.h>
25 #include "shared/devices.h"
26 #include "shared/common.h"
28 #include "shared/device-notifier.h"
29 #include "battery/power-supply.h"
31 #include "display-ops.h"
32 #include "display-panel.h"
33 #include "display-plugin.h"
34 #include "display-config.h"
35 #include "power/power-boot.h"
36 #include "shared/plugin.h"
43 static struct battery_plugin *battery_plgn;
44 static bool touchscreen_dev_available = false;
45 static int touchscreen_enable = DEVICE_OPS_STATUS_START;
46 static int powersaving_support = true;
48 static int touchscreen_start(enum device_flags flags);
49 static int touchscreen_stop(enum device_flags flags);
51 static int delayed_init_done(void *data);
53 static struct battery_status *battery = NULL;
55 static struct battery_status* (*fp_get_var_battery_status)(void);
57 static void touchscreen_wakeup_status(keynode_t *key, void *data)
62 if (!g_display_plugin.config)
65 g_display_plugin.config->touch_wakeup = vconf_keynode_get_bool(key);
67 if (display_panel_get_dpms_cached_state() != DPMS_ON) {
68 if (g_display_plugin.config->touch_wakeup)
69 touchscreen_start(NORMAL_MODE);
71 touchscreen_stop(TOUCH_SCREEN_OFF_MODE);
75 static int touchscreen_powersaving(enum ps_mode mode)
80 if (!powersaving_support)
83 if (touchscreen_enable != DEVICE_OPS_STATUS_START)
86 if (mode == POWERSAVING_ON)
88 else if (mode == POWERSAVING_OFF)
93 ret = hal_device_touchscreen_set_powersaving(state);
94 if (touchscreen_dev_available && (ret != -ENODEV)) {
96 _E("Failed to set touch powersaving node.");
101 _I("Set touch powersaving %s.", state ? "ON" : "OFF");
106 static int touchscreen_probe(void *data)
110 if (touchscreen_dev_available)
113 ret = hal_device_touchscreen_get_backend();
115 _E("There is no HAL for touchscreen.");
116 touchscreen_dev_available = false;
121 _I("Touchscreen device structure load success.");
122 touchscreen_dev_available = true;
127 static void touchscreen_exit(void *data)
129 touchscreen_dev_available = false;
130 hal_device_touchscreen_put_backend();
133 static int touchscreen_set_state(enum touchscreen_state state)
138 if (!touchscreen_dev_available) {
139 _E("Touchscreen device structure is not loaded.");
143 if (state != TOUCHSCREEN_ON && state != TOUCHSCREEN_OFF) {
144 _E("Invalid parameter.");
148 act = (state == TOUCHSCREEN_ON) ? "enable" : "disable";
150 ret = hal_device_touchscreen_set_state(state);
152 _I("Success to %s touchscreen.", act);
155 _E("Touchscreen set state is not supported.");
157 _E("Failed to %s touchscreen: %d", act, ret);
163 static int touchscreen_execute(void *data)
165 touchscreen_enable = (int)((intptr_t)data);
169 static int touchscreen_start(enum device_flags flags)
174 if (touchscreen_enable != DEVICE_OPS_STATUS_START)
177 /* Do not enable touchscreen during silent boot mode */
178 if (silent_boot && !delayed_init_done(NULL))
182 * It is safe to turn touchscreen on before powersaving on/off.
184 ret = touchscreen_set_state(TOUCHSCREEN_ON);
186 state = display_panel_get_dpms_cached_state();
188 if (state == DPMS_OFF)
189 touchscreen_powersaving(POWERSAVING_ON);
191 touchscreen_powersaving(POWERSAVING_OFF);
196 static int touchscreen_stop(enum device_flags flags)
198 if (!g_display_plugin.config) {
199 _I("Touchscreen is not initialized.");
204 * Touchscreen control priority
205 * 1. Touchscreen module control by execute(touchscreen_enable)
206 * 2. Device charger status by charging dock
207 * 3. Touch wakeup setting(touch_wakeup_enable) value
208 * 4. Normal mode(Basic request)
210 if (touchscreen_enable != DEVICE_OPS_STATUS_START)
213 if (flags & TOUCH_SCREEN_OFF_MODE) {
214 touchscreen_powersaving(POWERSAVING_OFF);
215 return touchscreen_set_state(TOUCHSCREEN_OFF);
218 if (battery && battery->charger_connected == 1) {
219 _I("Battery charging one %d %d.", battery->charger_connected, battery->online_type);
220 return touchscreen_powersaving(POWERSAVING_ON);
223 if (g_display_plugin.config->touch_wakeup) {
224 _I("Touch wakeup enabled.");
225 return touchscreen_powersaving(POWERSAVING_ON);
229 touchscreen_powersaving(POWERSAVING_OFF);
230 return touchscreen_set_state(TOUCHSCREEN_OFF);
233 static int touchscreen_dump(FILE *fp, int mode, void *dump_data)
235 enum touchscreen_state state;
238 ret = hal_device_touchscreen_get_state(&state);
239 if (!touchscreen_dev_available || (ret == -ENODEV))
243 _E("Failed to get touchscreen state: %d", ret);
247 if (state == TOUCHSCREEN_ON)
248 LOG_DUMP(fp, "Touchscreen is enabled\n");
250 LOG_DUMP(fp, "Touchscreen is disabled\n");
255 static GVariant *dbus_touchscreen_enable(GDBusConnection *conn,
256 const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
257 GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
260 ret = touchscreen_start(NORMAL_MODE);
262 return g_variant_new("(i)", ret);
265 static GVariant *dbus_touchscreen_disable(GDBusConnection *conn,
266 const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
267 GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
270 ret = touchscreen_stop(TOUCH_SCREEN_OFF_MODE);
272 return g_variant_new("(i)", ret);
275 static const dbus_method_s dbus_methods[] = {
276 { "Enable", NULL, "i", dbus_touchscreen_enable },
277 { "Disable", NULL, "i", dbus_touchscreen_disable },
278 /* Add methods here */
281 static const dbus_interface_u dbus_interface = {
283 .name = DEVICED_INTERFACE_TOUCH,
284 .methods = dbus_methods,
285 .nr_methods = ARRAY_SIZE(dbus_methods),
288 static int delayed_init_done(void *data)
290 static int done = false;
300 static void touchscreen_init(void *data)
304 if (battery_plgn->handle) {
305 fp_get_var_battery_status = dlsym(battery_plgn->handle, "get_var_battery_status");
306 if (fp_get_var_battery_status) {
307 battery = fp_get_var_battery_status();
309 _E("Failed to get battery status variable");
311 _E("Failed to obtain address of get_var_battery_status, %s.", dlerror());
313 _I("There is no battery module.");
315 ret = hal_device_touchscreen_set_powersaving(0);
316 if (touchscreen_dev_available && (ret != -ENODEV)) {
318 powersaving_support = false;
320 powersaving_support = true;
322 powersaving_support = false;
324 vconf_notify_key_changed(VCONFKEY_SETAPPL_TOUCH_WAKEUP_ENABLE,
325 touchscreen_wakeup_status, NULL);
326 ret = vconf_get_bool(VCONFKEY_SETAPPL_TOUCH_WAKEUP_ENABLE, &val);
327 if (g_display_plugin.config && ret == 0)
328 g_display_plugin.config->touch_wakeup = val;
331 ret = gdbus_add_object(NULL, DEVICED_PATH_TOUCH, &dbus_interface);
334 _E("Failed to init dbus method. (%d)", ret);
336 syscommon_notifier_subscribe_notify(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_done);
339 static const struct device_ops touchscreen_device_ops = {
340 DECLARE_NAME_LEN("touchscreen"),
341 .probe = touchscreen_probe,
342 .init = touchscreen_init,
343 .exit = touchscreen_exit,
344 .start = touchscreen_start,
345 .stop = touchscreen_stop,
346 .dump = touchscreen_dump,
347 .execute = touchscreen_execute,
350 DEVICE_OPS_REGISTER(&touchscreen_device_ops)
352 static void __CONSTRUCTOR__ initialize(void)
354 battery_plgn = get_var_battery_plugin();
356 _E("Failed to get battery plugin variable.");