4 * Copyright (c) 2015 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.
24 #include <linux/limits.h>
27 #include <hal/device/hal-battery-interface.h>
28 #include <hal/hal-common-interface.h>
29 #include <libsyscommon/file.h>
34 #define BATTERY_BUS "org.tizen.system.deviced"
35 #define BATTERY_OBJECT "/Org/Tizen/System/DeviceD/SysNoti"
36 #define BATTERY_IFACE BATTERY_BUS".SysNoti"
37 #define BATTERY_SIGNAL "power_supply"
39 #define FILE_BATTERY_CAPACITY "/sys/class/power_supply/battery/capacity"
40 #define FILE_BATTERY_CHARGER_ONLINE "/sys/devices/platform/jack/charger_online"
41 #define FILE_BATTERY_CHARGE_FULL "/sys/class/power_supply/battery/charge_full"
42 #define FILE_BATTERY_CHARGE_NOW "/sys/class/power_supply/battery/charge_now"
44 static struct signal_data {
45 BatteryUpdated updated_cb;
49 static int id; /* signal handler id */
51 static int get_power_source(int online, char **src)
58 *src = POWER_SOURCE_AC;
61 *src = POWER_SOURCE_USB;
64 *src = POWER_SOURCE_NONE;
71 static void signal_delivered(GDBusConnection *conn,
79 struct battery_info info;
81 char *sig, *capacity, *status, *health, *online, *present;
84 if (strncmp(signal, BATTERY_SIGNAL, sizeof(BATTERY_SIGNAL)))
87 _I("POWER_SUPPLY uevent is delivered");
89 if (!sdata.updated_cb) {
90 _E("POWER_SUPPLY callback is NULL");
94 g_variant_get(parameters, "(sisssss)", &sig, &num,
95 &capacity, &status, &health, &online, &present);
97 info.name = BATTERY_HARDWARE_DEVICE_ID;
100 info.online = atoi(online);
101 info.present = atoi(present);
102 info.capacity = atoi(capacity);
104 if (!strncmp(status, "Charging", strlen(status))) {
105 info.current_now = 1000; /* uA */
106 info.current_average = 1000; /* uA */
108 info.current_now = -1000; /* uA */
109 info.current_average = -1000; /* uA */
112 ret = get_power_source(info.online, &val);
115 info.power_source = val;
117 sdata.updated_cb(&info, sdata.data);
127 static int battery_register_changed_event(
128 BatteryUpdated updated_cb, void *data)
132 if (sdata.updated_cb) {
133 _E("update callback is already registered");
137 ret = register_dbus_signal(BATTERY_OBJECT,
138 BATTERY_IFACE, BATTERY_SIGNAL,
139 signal_delivered, &sdata, &id);
141 _E("Failed to register signal");
145 sdata.updated_cb = updated_cb;
151 static void battery_unregister_changed_event(
152 BatteryUpdated updated_cb)
154 unregister_dbus_signal(&id);
155 sdata.updated_cb = NULL;
159 static int battery_get_current_state(
160 BatteryUpdated updated_cb, void *data)
163 struct battery_info info;
166 char capacity_str[8];
168 char charge_full_str[8];
169 char charge_now_str[8];
170 int capacity, charger, charge_full, charge_now;
175 info.name = BATTERY_HARDWARE_DEVICE_ID;
177 ret = sys_get_str(FILE_BATTERY_CAPACITY, capacity_str, sizeof(capacity_str));
179 _E("Failed to get value of (%s, %d)", FILE_BATTERY_CAPACITY, ret);
183 /* When the TW emulator first accesses /sys/class/power_supply/battery/capacity,
184 it sometimes returns an empty string. */
185 if (capacity_str[0] == 0) {
186 _E("/sys/class/power_supply/battery/capacity returns null string, retry read it again");
187 ret = sys_get_str(FILE_BATTERY_CAPACITY, capacity_str, sizeof(capacity_str));
189 _E("Failed to get value of (%s, %d)", FILE_BATTERY_CAPACITY, ret);
194 ret = sys_get_str(FILE_BATTERY_CHARGER_ONLINE, charger_str, sizeof(charger_str));
196 _E("Failed to get value of (%s, %d)", FILE_BATTERY_CHARGER_ONLINE, ret);
199 ret = sys_get_str(FILE_BATTERY_CHARGE_FULL, charge_full_str, sizeof(charge_full_str));
201 _E("Failed to get value of (%s, %d)", FILE_BATTERY_CHARGE_FULL, ret);
204 ret = sys_get_str(FILE_BATTERY_CHARGE_NOW, charge_now_str, sizeof(charge_now_str));
206 _E("Failed to get value of (%s, %d)", FILE_BATTERY_CHARGE_NOW, ret);
210 capacity = atoi(capacity_str);
211 charger = atoi(charger_str);
212 charge_full = atoi(charge_full_str);
213 charge_now = atoi(charge_now_str);
215 if (charge_full == 1)
217 else if (charge_now == 1)
220 status = "Discharging";
221 info.status = status;
223 info.health = "Good";
224 info.online = charger + 1;
226 info.capacity = capacity;
228 if (charge_now == 1) {
229 info.current_now = 1000; /* uA */
230 info.current_average = 1000; /* uA */
232 info.current_now = -1000; /* uA */
233 info.current_average = -1000; /* uA */
236 /* Since there are no nodes for
237 * voltage_now, voltage_average, temperature
239 * use values similar to TM1.
241 info.voltage_now = 4000000;
242 info.voltage_average = 4000000;
244 info.temperature = 30;
246 ret = get_power_source(info.online, &val);
249 info.power_source = val;
251 updated_cb(&info, data);
256 static int battery_init(void **data)
258 hal_backend_battery_funcs *battery_funcs;
260 battery_funcs = calloc(1, sizeof(hal_backend_battery_funcs));
264 battery_funcs->register_changed_event = battery_register_changed_event;
265 battery_funcs->unregister_changed_event = battery_unregister_changed_event;
266 battery_funcs->get_current_state = battery_get_current_state;
268 *data = (void *)battery_funcs;
273 static int battery_exit(void *data)
282 hal_backend EXPORT hal_backend_device_battery_data = {
285 .abi_version = HAL_ABI_VERSION_TIZEN_6_5,
286 .init = battery_init,
287 .exit = battery_exit,