1868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev/*
2868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev * Copyright (C) 2012 The Android Open Source Project
3868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev *
4868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License");
5868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev * you may not use this file except in compliance with the License.
6868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev * You may obtain a copy of the License at
7868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev *
8868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev *      http://www.apache.org/licenses/LICENSE-2.0
9868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev *
10868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev * Unless required by applicable law or agreed to in writing, software
11868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS,
12868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev * See the License for the specific language governing permissions and
14868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev * limitations under the License.
15868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev */
16868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev#include <errno.h>
17868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev#include <string.h>
18868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev#include <sys/types.h>
19868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev#include <sys/stat.h>
20868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev#include <sys/socket.h>
21868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev#include <sys/un.h>
22868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev#include <fcntl.h>
23868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev#include <dlfcn.h>
24868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev
25b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev#define LOG_TAG "PowerHAL"
26868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev#include <utils/Log.h>
27868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev
28868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev#include <hardware/hardware.h>
29868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev#include <hardware/power.h>
3066e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
3166e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan#define STATE_ON "state=1"
3266e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan#define STATE_OFF "state=0"
331e661b89f8becf65469a34c6da75782747500529Mansoor Aftab#define STATE_HDR_ON "state=2"
341e661b89f8becf65469a34c6da75782747500529Mansoor Aftab#define STATE_HDR_OFF "state=3"
3566e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
36763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan#define MAX_LENGTH         50
3759fbd175b2373f8cafeafac594005fed412385aaMekala Natarajan#define BOOST_SOCKET       "/dev/socket/pb"
38868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev
39b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchevstatic int client_sockfd;
40b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchevstatic struct sockaddr_un client_addr;
4166e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajanstatic int last_state = -1;
4266e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
4366e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajanstatic void socket_init()
4466e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan{
4566e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    if (!client_sockfd) {
4666e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        client_sockfd = socket(PF_UNIX, SOCK_DGRAM, 0);
4766e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        if (client_sockfd < 0) {
4866e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan            ALOGE("%s: failed to open: %s", __func__, strerror(errno));
4966e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan            return;
5066e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        }
5166e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        memset(&client_addr, 0, sizeof(struct sockaddr_un));
5266e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        client_addr.sun_family = AF_UNIX;
5366e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        snprintf(client_addr.sun_path, UNIX_PATH_MAX, BOOST_SOCKET);
5466e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    }
5566e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan}
56868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev
57b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchevstatic void power_init(struct power_module *module)
58868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev{
59b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev    ALOGI("%s", __func__);
6066e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    socket_init();
6166e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan}
6266e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
6366e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajanstatic void sync_thread(int off)
6466e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan{
6566e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    int rc;
66763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan    pid_t client;
67763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan    char data[MAX_LENGTH];
6866e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
6966e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    if (client_sockfd < 0) {
7066e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        ALOGE("%s: boost socket not created", __func__);
7166e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        return;
7266e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    }
7366e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
74763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan    client = getpid();
75763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan
7666e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    if (!off) {
77763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan        snprintf(data, MAX_LENGTH, "2:%d", client);
78763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan        rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
7966e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    } else {
80763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan        snprintf(data, MAX_LENGTH, "3:%d", client);
81763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan        rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
8266e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    }
8366e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
8466e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    if (rc < 0) {
8566e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        ALOGE("%s: failed to send: %s", __func__, strerror(errno));
8666e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    }
8766e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan}
8866e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
891e661b89f8becf65469a34c6da75782747500529Mansoor Aftabstatic void enc_boost(int off)
901e661b89f8becf65469a34c6da75782747500529Mansoor Aftab{
911e661b89f8becf65469a34c6da75782747500529Mansoor Aftab    int rc;
921e661b89f8becf65469a34c6da75782747500529Mansoor Aftab    pid_t client;
931e661b89f8becf65469a34c6da75782747500529Mansoor Aftab    char data[MAX_LENGTH];
941e661b89f8becf65469a34c6da75782747500529Mansoor Aftab
951e661b89f8becf65469a34c6da75782747500529Mansoor Aftab    if (client_sockfd < 0) {
961e661b89f8becf65469a34c6da75782747500529Mansoor Aftab        ALOGE("%s: boost socket not created", __func__);
971e661b89f8becf65469a34c6da75782747500529Mansoor Aftab        return;
981e661b89f8becf65469a34c6da75782747500529Mansoor Aftab    }
991e661b89f8becf65469a34c6da75782747500529Mansoor Aftab
1001e661b89f8becf65469a34c6da75782747500529Mansoor Aftab    client = getpid();
1011e661b89f8becf65469a34c6da75782747500529Mansoor Aftab
1021e661b89f8becf65469a34c6da75782747500529Mansoor Aftab    if (!off) {
1031e661b89f8becf65469a34c6da75782747500529Mansoor Aftab        snprintf(data, MAX_LENGTH, "5:%d", client);
1041e661b89f8becf65469a34c6da75782747500529Mansoor Aftab        rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
1051e661b89f8becf65469a34c6da75782747500529Mansoor Aftab    } else {
1061e661b89f8becf65469a34c6da75782747500529Mansoor Aftab        snprintf(data, MAX_LENGTH, "6:%d", client);
1071e661b89f8becf65469a34c6da75782747500529Mansoor Aftab        rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
1081e661b89f8becf65469a34c6da75782747500529Mansoor Aftab    }
1091e661b89f8becf65469a34c6da75782747500529Mansoor Aftab
1101e661b89f8becf65469a34c6da75782747500529Mansoor Aftab    if (rc < 0) {
1111e661b89f8becf65469a34c6da75782747500529Mansoor Aftab        ALOGE("%s: failed to send: %s", __func__, strerror(errno));
1121e661b89f8becf65469a34c6da75782747500529Mansoor Aftab    }
1131e661b89f8becf65469a34c6da75782747500529Mansoor Aftab}
1141e661b89f8becf65469a34c6da75782747500529Mansoor Aftab
11566e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajanstatic void process_video_encode_hint(void *metadata)
11666e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan{
11766e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
11866e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    socket_init();
11966e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
120b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev    if (client_sockfd < 0) {
12166e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        ALOGE("%s: boost socket not created", __func__);
122868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev        return;
123868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev    }
12466e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
12566e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    if (metadata) {
12666e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        if (!strncmp(metadata, STATE_ON, sizeof(STATE_ON))) {
12766e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan            /* Video encode started */
12866e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan            sync_thread(1);
129ff9f4538c09399030fa73e3e65a167852cb91e8fShuzhen Wang            enc_boost(1);
13066e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        } else if (!strncmp(metadata, STATE_OFF, sizeof(STATE_OFF))) {
13166e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan            /* Video encode stopped */
13266e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan            sync_thread(0);
133ff9f4538c09399030fa73e3e65a167852cb91e8fShuzhen Wang            enc_boost(0);
1341e661b89f8becf65469a34c6da75782747500529Mansoor Aftab        }  else if (!strncmp(metadata, STATE_HDR_ON, sizeof(STATE_HDR_ON))) {
1351e661b89f8becf65469a34c6da75782747500529Mansoor Aftab            /* HDR usecase started */
1361e661b89f8becf65469a34c6da75782747500529Mansoor Aftab        } else if (!strncmp(metadata, STATE_HDR_OFF, sizeof(STATE_HDR_OFF))) {
1371e661b89f8becf65469a34c6da75782747500529Mansoor Aftab            /* HDR usecase stopped */
1381e661b89f8becf65469a34c6da75782747500529Mansoor Aftab        }else
13966e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan            return;
14066e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    } else {
14166e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        return;
14266e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    }
143b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev}
144868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev
14566e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
146b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchevstatic void touch_boost()
147b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev{
148b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev    int rc;
149763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan    pid_t client;
150763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan    char data[MAX_LENGTH];
151868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev
152b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev    if (client_sockfd < 0) {
15366e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        ALOGE("%s: boost socket not created", __func__);
154b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev        return;
155868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev    }
156868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev
157763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan    client = getpid();
158763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan
159763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan    snprintf(data, MAX_LENGTH, "1:%d", client);
160763363745be3aa2ad10005d5a30a29e84d69c425Mekala Natarajan    rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un));
161b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev    if (rc < 0) {
162b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev        ALOGE("%s: failed to send: %s", __func__, strerror(errno));
163868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev    }
164868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev}
165868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev
166b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchevstatic void power_set_interactive(struct power_module *module, int on)
167b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev{
16866e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    if (last_state == -1) {
16966e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        last_state = on;
17066e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    } else {
17166e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        if (last_state == on)
17266e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan            return;
17366e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        else
17466e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan            last_state = on;
17566e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    }
17666e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan
177b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev    ALOGV("%s %s", __func__, (on ? "ON" : "OFF"));
17866e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    if (on) {
17966e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        sync_thread(0);
180b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev        touch_boost();
18166e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    } else {
18266e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        sync_thread(1);
18366e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan    }
184b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev}
185b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev
186868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchevstatic void power_hint(struct power_module *module, power_hint_t hint,
187868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev                       void *data) {
188868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev    switch (hint) {
189868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev        case POWER_HINT_INTERACTION:
190b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev            ALOGV("POWER_HINT_INTERACTION");
191868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev            touch_boost();
192b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev            break;
193b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev#if 0
194b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev        case POWER_HINT_VSYNC:
195b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev            ALOGV("POWER_HINT_VSYNC %s", (data ? "ON" : "OFF"));
196b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev            break;
197b59998fa25f217ba651f6f5a4f1ddcdb0d24b42dIliyan Malchev#endif
19866e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan        case POWER_HINT_VIDEO_ENCODE:
19966e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan            process_video_encode_hint(data);
20066e5ad149393a5875253cb7db290f9731d1f3c7aMekala Natarajan            break;
201868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev        default:
202868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev             break;
203868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev    }
204868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev}
205868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev
206868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchevstatic struct hw_module_methods_t power_module_methods = {
207868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev    .open = NULL,
208868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev};
209868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev
210868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchevstruct power_module HAL_MODULE_INFO_SYM = {
211868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev    .common = {
212868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev        .tag = HARDWARE_MODULE_TAG,
213868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev        .module_api_version = POWER_MODULE_API_VERSION_0_2,
214868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev        .hal_api_version = HARDWARE_HAL_API_VERSION,
215868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev        .id = POWER_HARDWARE_MODULE_ID,
216868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev        .name = "Qualcomm Power HAL",
217868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev        .author = "The Android Open Source Project",
218868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev        .methods = &power_module_methods,
219868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev    },
220868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev
221868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev    .init = power_init,
222868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev    .setInteractive = power_set_interactive,
223868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev    .powerHint = power_hint,
224868f7635b2b57d883a3978b3837a58aecc0d7131Iliyan Malchev};
225