blob: 35946db58cd4702c000e3b51325282327cea113b [file] [log] [blame]
Christopher N. Hessede5e3c62015-12-21 21:28:23 +01001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 * Copyright (C) 2014 The CyanogenMod Project
4 * Copyright (C) 2014-2015 Andreas Schneider <asn@cryptomilk.org>
Christopher N. Hessef05f9022017-01-16 22:49:06 +01005 * Copyright (C) 2014-2017 Christopher N. Hesse <raymanfx@gmail.com>
Christopher N. Hessede5e3c62015-12-21 21:28:23 +01006 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
Christopher N. Hesse3360b092016-07-11 15:48:35 +020020#include <ctype.h>
Christopher N. Hessede5e3c62015-12-21 21:28:23 +010021#include <dirent.h>
22#include <errno.h>
23#include <fcntl.h>
24#include <malloc.h>
25#include <stdbool.h>
Christopher N. Hessee1434192016-11-18 18:56:17 +010026#include <stdlib.h>
Christopher N. Hessede5e3c62015-12-21 21:28:23 +010027#include <string.h>
28#include <unistd.h>
29
30#include <sys/types.h>
31#include <sys/stat.h>
32
33#define LOG_TAG "SamsungPowerHAL"
34/* #define LOG_NDEBUG 0 */
35#include <utils/Log.h>
36
37#include <hardware/hardware.h>
38#include <hardware/power.h>
Christopher N. Hesse12263502016-12-07 12:18:20 +010039#include <liblights/samsung_lights_helper.h>
Christopher N. Hessede5e3c62015-12-21 21:28:23 +010040
Christopher N. Hesse4139d852016-12-07 12:21:44 +010041#include "samsung_power.h"
Christopher N. Hessede5e3c62015-12-21 21:28:23 +010042
Christopher N. Hessed9106e92017-03-04 01:05:14 +010043#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
44
Christopher N. Hessede5e3c62015-12-21 21:28:23 +010045struct samsung_power_module {
46 struct power_module base;
47 pthread_mutex_t lock;
48 int boostpulse_fd;
Christopher N. Hessede5e3c62015-12-21 21:28:23 +010049 char cpu0_hispeed_freq[10];
50 char cpu0_max_freq[10];
51 char cpu4_hispeed_freq[10];
52 char cpu4_max_freq[10];
53 char* touchscreen_power_path;
54 char* touchkey_power_path;
Christopher N. Hessede5e3c62015-12-21 21:28:23 +010055};
56
Andreas Schneiderf15d7f42016-02-03 10:43:47 +010057enum power_profile_e {
58 PROFILE_POWER_SAVE = 0,
59 PROFILE_BALANCED,
Christopher N. Hesse58f2ca02017-01-17 00:01:15 +010060 PROFILE_HIGH_PERFORMANCE,
61 PROFILE_MAX
Andreas Schneiderf15d7f42016-02-03 10:43:47 +010062};
Christopher N. Hesseccd970d2017-01-25 22:41:05 +010063
Andreas Schneiderf15d7f42016-02-03 10:43:47 +010064static enum power_profile_e current_power_profile = PROFILE_BALANCED;
Christopher N. Hesseccd970d2017-01-25 22:41:05 +010065static bool boostpulse_warned = false;
Christopher N. Hessede5e3c62015-12-21 21:28:23 +010066
67/**********************************************************
68 *** HELPER FUNCTIONS
69 **********************************************************/
70
71static int sysfs_read(char *path, char *s, int num_bytes)
72{
73 char errno_str[64];
74 int len;
75 int ret = 0;
76 int fd;
77
78 fd = open(path, O_RDONLY);
79 if (fd < 0) {
80 strerror_r(errno, errno_str, sizeof(errno_str));
Christopher N. Hesse354f7132017-03-04 01:06:22 +010081 ALOGE("Error opening %s: %s", path, errno_str);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +010082
83 return -1;
84 }
85
86 len = read(fd, s, num_bytes - 1);
87 if (len < 0) {
88 strerror_r(errno, errno_str, sizeof(errno_str));
Christopher N. Hesse354f7132017-03-04 01:06:22 +010089 ALOGE("Error reading from %s: %s", path, errno_str);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +010090
91 ret = -1;
92 } else {
93 s[len] = '\0';
94 }
95
96 close(fd);
97
98 return ret;
99}
100
101static void sysfs_write(const char *path, char *s)
102{
103 char errno_str[64];
104 int len;
105 int fd;
106
107 fd = open(path, O_WRONLY);
108 if (fd < 0) {
109 strerror_r(errno, errno_str, sizeof(errno_str));
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100110 ALOGE("Error opening %s: %s", path, errno_str);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100111 return;
112 }
113
114 len = write(fd, s, strlen(s));
115 if (len < 0) {
116 strerror_r(errno, errno_str, sizeof(errno_str));
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100117 ALOGE("Error writing to %s: %s", path, errno_str);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100118 }
119
120 close(fd);
121}
122
Christopher N. Hesse5fada9b2017-01-16 23:39:48 +0100123static void boost(int32_t duration_us)
124{
125 int fd;
126
127 if (duration_us <= 0)
128 return;
129
130 fd = open(BOOST_PATH, O_WRONLY);
131 if (fd < 0) {
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100132 ALOGE("Error opening %s", BOOST_PATH);
Christopher N. Hesse5fada9b2017-01-16 23:39:48 +0100133 return;
134 }
135
136 write(fd, "1", 1);
137 usleep(duration_us);
138 write(fd, "0", 1);
139
140 close(fd);
141}
142
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100143/**********************************************************
144 *** POWER FUNCTIONS
145 **********************************************************/
146
147/* You need to request the powerhal lock before calling this function */
148static int boostpulse_open(struct samsung_power_module *samsung_pwr)
149{
150 char errno_str[64];
151
152 if (samsung_pwr->boostpulse_fd < 0) {
153 samsung_pwr->boostpulse_fd = open(BOOSTPULSE_PATH, O_WRONLY);
154 if (samsung_pwr->boostpulse_fd < 0) {
Christopher N. Hesseccd970d2017-01-25 22:41:05 +0100155 if (!boostpulse_warned) {
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100156 strerror_r(errno, errno_str, sizeof(errno_str));
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100157 ALOGE("Error opening %s: %s", BOOSTPULSE_PATH, errno_str);
Christopher N. Hesseccd970d2017-01-25 22:41:05 +0100158 boostpulse_warned = true;
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100159 }
160 }
161 }
162
163 return samsung_pwr->boostpulse_fd;
164}
165
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100166static void set_power_profile(struct samsung_power_module *samsung_pwr,
Christopher N. Hesse58f2ca02017-01-17 00:01:15 +0100167 int profile)
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100168{
169 int rc;
170 struct stat sb;
171
Christopher N. Hesse58f2ca02017-01-17 00:01:15 +0100172 if (profile < 0 || profile >= PROFILE_MAX) {
173 return;
174 }
175
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100176 if (current_power_profile == profile) {
177 return;
178 }
179
180 ALOGV("%s: profile=%d", __func__, profile);
181
182 switch (profile) {
183 case PROFILE_POWER_SAVE:
184 // Limit to hispeed freq
185 sysfs_write(CPU0_MAX_FREQ_PATH, samsung_pwr->cpu0_hispeed_freq);
186 rc = stat(CPU4_MAX_FREQ_PATH, &sb);
187 if (rc == 0) {
188 sysfs_write(CPU4_MAX_FREQ_PATH, samsung_pwr->cpu4_hispeed_freq);
189 }
Christopher N. Hessef05f9022017-01-16 22:49:06 +0100190 ALOGV("%s: set powersave mode", __func__);
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100191 break;
192 case PROFILE_BALANCED:
193 // Restore normal max freq
194 sysfs_write(CPU0_MAX_FREQ_PATH, samsung_pwr->cpu0_max_freq);
195 rc = stat(CPU4_MAX_FREQ_PATH, &sb);
196 if (rc == 0) {
197 sysfs_write(CPU4_MAX_FREQ_PATH, samsung_pwr->cpu4_max_freq);
198 }
Christopher N. Hessef05f9022017-01-16 22:49:06 +0100199 ALOGV("%s: set balanced mode", __func__);
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100200 break;
201 case PROFILE_HIGH_PERFORMANCE:
202 // Restore normal max freq
203 sysfs_write(CPU0_MAX_FREQ_PATH, samsung_pwr->cpu0_max_freq);
204 rc = stat(CPU4_MAX_FREQ_PATH, &sb);
205 if (rc == 0) {
206 sysfs_write(CPU4_MAX_FREQ_PATH, samsung_pwr->cpu4_max_freq);
207 }
Christopher N. Hessef05f9022017-01-16 22:49:06 +0100208 ALOGV("%s: set performance mode", __func__);
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100209 break;
210 }
211
212 current_power_profile = profile;
213}
214
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100215static void find_input_nodes(struct samsung_power_module *samsung_pwr, char *dir)
216{
217 const char filename[] = "name";
218 char errno_str[64];
219 struct dirent *de;
220 char file_content[20];
221 char *path = NULL;
222 char *node_path = NULL;
223 size_t pathsize;
224 size_t node_pathsize;
225 DIR *d;
226
227 d = opendir(dir);
228 if (d == NULL) {
229 return;
230 }
231
232 while ((de = readdir(d)) != NULL) {
233 if (strncmp(filename, de->d_name, sizeof(filename)) == 0) {
234 pathsize = strlen(dir) + strlen(de->d_name) + 2;
235 node_pathsize = strlen(dir) + strlen("enabled") + 2;
236
237 path = malloc(pathsize);
238 node_path = malloc(node_pathsize);
239 if (path == NULL || node_path == NULL) {
240 strerror_r(errno, errno_str, sizeof(errno_str));
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100241 ALOGE("Out of memory: %s", errno_str);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100242 return;
243 }
244
245 snprintf(path, pathsize, "%s/%s", dir, filename);
246 sysfs_read(path, file_content, sizeof(file_content));
247
248 snprintf(node_path, node_pathsize, "%s/%s", dir, "enabled");
249
250 if (strncmp(file_content, "sec_touchkey", 12) == 0) {
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100251 ALOGV("%s: found touchkey path: %s", __func__, node_path);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100252 samsung_pwr->touchkey_power_path = malloc(node_pathsize);
253 if (samsung_pwr->touchkey_power_path == NULL) {
254 strerror_r(errno, errno_str, sizeof(errno_str));
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100255 ALOGE("Out of memory: %s", errno_str);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100256 return;
257 }
Christopher N. Hesse22da3132016-02-01 12:36:54 +0100258 snprintf(samsung_pwr->touchkey_power_path, node_pathsize,
259 "%s", node_path);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100260 }
261
262 if (strncmp(file_content, "sec_touchscreen", 15) == 0) {
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100263 ALOGV("%s: found touchscreen path: %s", __func__, node_path);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100264 samsung_pwr->touchscreen_power_path = malloc(node_pathsize);
265 if (samsung_pwr->touchscreen_power_path == NULL) {
266 strerror_r(errno, errno_str, sizeof(errno_str));
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100267 ALOGE("Out of memory: %s", errno_str);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100268 return;
269 }
Christopher N. Hesse22da3132016-02-01 12:36:54 +0100270 snprintf(samsung_pwr->touchscreen_power_path, node_pathsize,
271 "%s", node_path);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100272 }
273 }
274 }
275
276 if (path)
277 free(path);
278 if (node_path)
279 free(node_path);
280 closedir(d);
281}
282
283/**********************************************************
284 *** INIT FUNCTIONS
285 **********************************************************/
286
287static void init_cpufreqs(struct samsung_power_module *samsung_pwr)
288{
289 int rc;
290 struct stat sb;
291
292 sysfs_read(CPU0_HISPEED_FREQ_PATH, samsung_pwr->cpu0_hispeed_freq,
293 sizeof(samsung_pwr->cpu0_hispeed_freq));
294 sysfs_read(CPU0_MAX_FREQ_PATH, samsung_pwr->cpu0_max_freq,
295 sizeof(samsung_pwr->cpu0_max_freq));
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100296 ALOGV("%s: CPU 0 hispeed freq: %s", __func__, samsung_pwr->cpu0_hispeed_freq);
297 ALOGV("%s: CPU 0 max freq: %s", __func__, samsung_pwr->cpu0_max_freq);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100298
299 rc = stat(CPU4_HISPEED_FREQ_PATH, &sb);
300 if (rc == 0) {
301 sysfs_read(CPU4_HISPEED_FREQ_PATH, samsung_pwr->cpu4_hispeed_freq,
302 sizeof(samsung_pwr->cpu4_hispeed_freq));
303 sysfs_read(CPU4_MAX_FREQ_PATH, samsung_pwr->cpu4_max_freq,
304 sizeof(samsung_pwr->cpu4_max_freq));
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100305 ALOGV("%s: CPU 4 hispeed freq: %s", __func__, samsung_pwr->cpu4_hispeed_freq);
306 ALOGV("%s: CPU 4 max freq: %s", __func__, samsung_pwr->cpu4_max_freq);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100307 }
308}
309
310static void init_touch_input_power_path(struct samsung_power_module *samsung_pwr)
311{
312 char dir[1024];
313 char errno_str[64];
314 uint32_t i;
315
316 for (i = 0; i < 20; i++) {
317 snprintf(dir, sizeof(dir), "/sys/class/input/input%d", i);
318 find_input_nodes(samsung_pwr, dir);
319 }
320}
321
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100322static void samsung_power_init(struct power_module *module)
323{
324 struct samsung_power_module *samsung_pwr = (struct samsung_power_module *) module;
325
326 init_cpufreqs(samsung_pwr);
Christopher N. Hessed9106e92017-03-04 01:05:14 +0100327
328 boostpulse_open(samsung_pwr);
329
Christopher N. Hesse65c65bd2017-03-07 23:01:12 +0100330 samsung_pwr->touchscreen_power_path = NULL;
331 samsung_pwr->touchkey_power_path = NULL;
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100332 init_touch_input_power_path(samsung_pwr);
333}
334
Christopher N. Hessef6296722017-01-16 22:47:11 +0100335/**********************************************************
336 *** API FUNCTIONS
337 ***
338 *** Refer to power.h for documentation.
339 **********************************************************/
340
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100341static void samsung_power_set_interactive(struct power_module *module, int on)
342{
343 struct samsung_power_module *samsung_pwr = (struct samsung_power_module *) module;
344 struct stat sb;
Christopher N. Hessed9106e92017-03-04 01:05:14 +0100345 int panel_brightness;
346 char button_state[2];
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100347 int rc;
Christopher N. Hessed9106e92017-03-04 01:05:14 +0100348 static bool touchkeys_blocked = false;
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100349
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100350 ALOGV("power_set_interactive: %d", on);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100351
Christopher N. Hessed9106e92017-03-04 01:05:14 +0100352 /*
353 * Do not disable any input devices if the screen is on but we are in a non-interactive
354 * state.
355 */
Christopher N. Hesse3360b092016-07-11 15:48:35 +0200356 if (!on) {
Christopher N. Hessed9106e92017-03-04 01:05:14 +0100357 panel_brightness = get_cur_panel_brightness();
358 if (panel_brightness < 0) {
359 ALOGE("%s: Failed to read panel brightness", __func__);
360 } else if (panel_brightness > 0) {
Christopher N. Hesse3360b092016-07-11 15:48:35 +0200361 ALOGV("%s: Moving to non-interactive state, but screen is still on,"
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100362 " not disabling input devices", __func__);
Christopher N. Hesse3360b092016-07-11 15:48:35 +0200363 goto out;
364 }
365 }
366
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100367 sysfs_write(samsung_pwr->touchscreen_power_path, on ? "1" : "0");
368
Christopher N. Hessed9106e92017-03-04 01:05:14 +0100369 /* Bail out if the device does not have touchkeys */
370 if (samsung_pwr->touchkey_power_path == NULL) {
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100371 goto out;
372 }
373
374 if (!on) {
Christopher N. Hessed9106e92017-03-04 01:05:14 +0100375 rc = sysfs_read(samsung_pwr->touchkey_power_path, button_state, ARRAY_SIZE(button_state));
376 if (rc < 0) {
377 ALOGE("%s: Failed to read touchkey state", __func__);
378 goto out;
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100379 }
Christopher N. Hessed9106e92017-03-04 01:05:14 +0100380 /*
381 * If button_state is 0, the keys have been disabled by another component
382 * (for example cmhw), which means we don't want them to be enabled when resuming
383 * from suspend.
384 */
385 if (button_state[0] == '0') {
386 touchkeys_blocked = true;
387 } else {
388 touchkeys_blocked = false;
389 }
390 }
391
392 if (!touchkeys_blocked) {
393 sysfs_write(samsung_pwr->touchkey_power_path, on ? "1" : "0");
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100394 }
395
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100396out:
Christopher N. Hesse2879c692016-07-11 15:49:49 +0200397 sysfs_write(IO_IS_BUSY_PATH, on ? "1" : "0");
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100398 ALOGV("power_set_interactive: %d done", on);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100399}
400
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100401static void samsung_power_hint(struct power_module *module,
402 power_hint_t hint,
403 void *data)
404{
405 struct samsung_power_module *samsung_pwr = (struct samsung_power_module *) module;
406 char errno_str[64];
407 int len;
408
409 switch (hint) {
410 case POWER_HINT_INTERACTION: {
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100411 if (current_power_profile == PROFILE_POWER_SAVE) {
412 return;
413 }
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100414
415 ALOGV("%s: POWER_HINT_INTERACTION", __func__);
416
417 if (boostpulse_open(samsung_pwr) >= 0) {
418 len = write(samsung_pwr->boostpulse_fd, "1", 1);
419
420 if (len < 0) {
421 strerror_r(errno, errno_str, sizeof(errno_str));
Christopher N. Hesse354f7132017-03-04 01:06:22 +0100422 ALOGE("Error writing to %s: %s", BOOSTPULSE_PATH, errno_str);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100423 }
424 }
425
426 break;
427 }
428 case POWER_HINT_VSYNC: {
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100429 ALOGV("%s: POWER_HINT_VSYNC", __func__);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100430 break;
431 }
Christopher N. Hesse5fada9b2017-01-16 23:39:48 +0100432#ifdef POWER_HINT_CPU_BOOST
433 case POWER_HINT_CPU_BOOST:
434 boost((*(int32_t *)data));
435 break;
436#endif
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100437 case POWER_HINT_SET_PROFILE: {
438 int profile = *((intptr_t *)data);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100439
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100440 ALOGV("%s: POWER_HINT_SET_PROFILE", __func__);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100441
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100442 set_power_profile(samsung_pwr, profile);
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100443 break;
444 }
445 default:
446 break;
447 }
448}
449
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100450static int samsung_get_feature(struct power_module *module __unused,
451 feature_t feature)
452{
453 if (feature == POWER_FEATURE_SUPPORTED_PROFILES) {
Christopher N. Hesse58f2ca02017-01-17 00:01:15 +0100454 return PROFILE_MAX;
Andreas Schneiderf15d7f42016-02-03 10:43:47 +0100455 }
456
457 return -1;
458}
459
Christopher N. Hesse1c474662016-11-18 18:59:06 +0100460static void samsung_set_feature(struct power_module *module, feature_t feature, int state __unused)
Christopher N. Hessee480d892016-06-22 23:04:39 +0200461{
462 struct samsung_power_module *samsung_pwr = (struct samsung_power_module *) module;
463
464 switch (feature) {
ishantvivek987dcca2016-11-21 06:05:47 +0000465#ifdef TARGET_TAP_TO_WAKE_NODE
Christopher N. Hessee480d892016-06-22 23:04:39 +0200466 case POWER_FEATURE_DOUBLE_TAP_TO_WAKE:
467 ALOGV("%s: %s double tap to wake", __func__, state ? "enabling" : "disabling");
ishantvivek987dcca2016-11-21 06:05:47 +0000468 sysfs_write(TARGET_TAP_TO_WAKE_NODE, state > 0 ? "1" : "0");
Christopher N. Hessee480d892016-06-22 23:04:39 +0200469 break;
470#endif
471 default:
472 break;
473 }
474}
475
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100476static struct hw_module_methods_t power_module_methods = {
477 .open = NULL,
478};
479
480struct samsung_power_module HAL_MODULE_INFO_SYM = {
481 .base = {
482 .common = {
483 .tag = HARDWARE_MODULE_TAG,
484 .module_api_version = POWER_MODULE_API_VERSION_0_2,
485 .hal_api_version = HARDWARE_HAL_API_VERSION,
486 .id = POWER_HARDWARE_MODULE_ID,
487 .name = "Samsung Power HAL",
Christopher N. Hesseaa75be42017-01-16 22:47:59 +0100488 .author = "The LineageOS Project",
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100489 .methods = &power_module_methods,
490 },
491
492 .init = samsung_power_init,
493 .setInteractive = samsung_power_set_interactive,
494 .powerHint = samsung_power_hint,
Christopher N. Hessee480d892016-06-22 23:04:39 +0200495 .getFeature = samsung_get_feature,
496 .setFeature = samsung_set_feature
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100497 },
498
499 .lock = PTHREAD_MUTEX_INITIALIZER,
500 .boostpulse_fd = -1,
Christopher N. Hessede5e3c62015-12-21 21:28:23 +0100501};