b6447cf9703c73d828a2bf97178b9605b8001e48
[pcsx_rearmed.git] / frontend / plat_pandora.c
1 /*
2  * (C) notaz, 2011
3  *
4  * This work is licensed under the terms of the GNU GPLv2 or later.
5  * See the COPYING file in the top-level directory.
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <sys/ioctl.h>
15 #include <unistd.h>
16 #include <linux/input.h>
17 #include <dirent.h>
18 #include <errno.h>
19
20 #include "common/input.h"
21 #include "linux/in_evdev.h"
22 #include "plugin_lib.h"
23 #include "plat.h"
24 #include "plat_omap.h"
25 #include "main.h"
26 #include "menu.h"
27
28 static const char * const pandora_gpio_keys[KEY_MAX + 1] = {
29         [0 ... KEY_MAX] = NULL,
30         [KEY_UP]        = "Up",
31         [KEY_LEFT]      = "Left",
32         [KEY_RIGHT]     = "Right",
33         [KEY_DOWN]      = "Down",
34         [KEY_HOME]      = "(A)",
35         [KEY_PAGEDOWN]  = "(X)",
36         [KEY_END]       = "(B)",
37         [KEY_PAGEUP]    = "(Y)",
38         [KEY_RIGHTSHIFT]= "(L)",
39         [KEY_RIGHTCTRL] = "(R)",
40         [KEY_LEFTALT]   = "Start",
41         [KEY_LEFTCTRL]  = "Select",
42         [KEY_MENU]      = "Pandora",
43 };
44
45 static const struct in_default_bind in_evdev_defbinds[] = {
46         { KEY_UP,       IN_BINDTYPE_PLAYER12, DKEY_UP },
47         { KEY_DOWN,     IN_BINDTYPE_PLAYER12, DKEY_DOWN },
48         { KEY_LEFT,     IN_BINDTYPE_PLAYER12, DKEY_LEFT },
49         { KEY_RIGHT,    IN_BINDTYPE_PLAYER12, DKEY_RIGHT },
50         { KEY_PAGEUP,   IN_BINDTYPE_PLAYER12, DKEY_TRIANGLE },
51         { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, DKEY_CROSS },
52         { KEY_END,      IN_BINDTYPE_PLAYER12, DKEY_CIRCLE },
53         { KEY_HOME,     IN_BINDTYPE_PLAYER12, DKEY_SQUARE },
54         { KEY_LEFTALT,  IN_BINDTYPE_PLAYER12, DKEY_START },
55         { KEY_LEFTCTRL, IN_BINDTYPE_PLAYER12, DKEY_SELECT },
56         { KEY_RIGHTSHIFT,IN_BINDTYPE_PLAYER12, DKEY_L1 },
57         { KEY_RIGHTCTRL, IN_BINDTYPE_PLAYER12, DKEY_R1 },
58         { KEY_Q,        IN_BINDTYPE_PLAYER12, DKEY_L2 },
59         { KEY_P,        IN_BINDTYPE_PLAYER12, DKEY_R2 },
60         { KEY_MENU,     IN_BINDTYPE_EMU, SACTION_MINIMIZE },
61         { KEY_SPACE,    IN_BINDTYPE_EMU, SACTION_ENTER_MENU },
62         { KEY_1,        IN_BINDTYPE_EMU, SACTION_SAVE_STATE },
63         { KEY_2,        IN_BINDTYPE_EMU, SACTION_LOAD_STATE },
64         { KEY_3,        IN_BINDTYPE_EMU, SACTION_PREV_SSLOT },
65         { KEY_4,        IN_BINDTYPE_EMU, SACTION_NEXT_SSLOT },
66         { KEY_5,        IN_BINDTYPE_EMU, SACTION_TOGGLE_FSKIP },
67         { KEY_6,        IN_BINDTYPE_EMU, SACTION_SCREENSHOT },
68         { KEY_7,        IN_BINDTYPE_EMU, SACTION_TOGGLE_RENDERER },
69         { 0, 0, 0 }
70 };
71
72 static const char pnd_script_base[] = "sudo -n /usr/pandora/scripts";
73 static char **pnd_filter_list;
74
75 static void scan_for_filters(void)
76 {
77         struct dirent *ent;
78         int i, count = 0;
79         char **mfilters;
80         char buff[64];
81         DIR *dir;
82
83         dir = opendir("/etc/pandora/conf/dss_fir");
84         if (dir == NULL) {
85                 perror("filter opendir");
86                 return;
87         }
88
89         while (1) {
90                 errno = 0;
91                 ent = readdir(dir);
92                 if (ent == NULL) {
93                         if (errno != 0)
94                                 perror("readdir");
95                         break;
96                 }
97
98                 if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
99                         continue;
100
101                 count++;
102         }
103
104         if (count == 0)
105                 return;
106
107         mfilters = calloc(count + 1, sizeof(mfilters[0]));
108         if (mfilters == NULL)
109                 return;
110
111         rewinddir(dir);
112         for (i = 0; (ent = readdir(dir)); ) {
113                 size_t len;
114
115                 if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
116                         continue;
117
118                 len = strlen(ent->d_name);
119
120                 // skip pre-HF5 extra files
121                 if (len >= 3 && strcmp(ent->d_name + len - 3, "_v3") == 0)
122                         continue;
123                 if (len >= 3 && strcmp(ent->d_name + len - 3, "_v5") == 0)
124                         continue;
125
126                 // have to cut "_up_h" for pre-HF5
127                 if (len > 5 && strcmp(ent->d_name + len - 5, "_up_h") == 0)
128                         len -= 5;
129
130                 if (len > sizeof(buff) - 1)
131                         continue;
132
133                 strncpy(buff, ent->d_name, len);
134                 buff[len] = 0;
135                 mfilters[i] = strdup(buff);
136                 if (mfilters[i] != NULL)
137                         i++;
138         }
139         closedir(dir);
140
141         pnd_filter_list = mfilters;
142         menu_set_filter_list((void *)mfilters);
143 }
144
145 int plat_init(void)
146 {
147         int gpiokeys_id;
148
149         plat_omap_init();
150
151         in_evdev_init(in_evdev_defbinds);
152         in_probe();
153         gpiokeys_id = in_name_to_id("evdev:gpio-keys");
154         in_set_config(gpiokeys_id, IN_CFG_KEY_NAMES,
155                       pandora_gpio_keys, sizeof(pandora_gpio_keys));
156         in_set_config(gpiokeys_id, IN_CFG_DEFAULT_DEV, NULL, 0);
157         in_adev[0] = in_name_to_id("evdev:nub0");
158         in_adev[1] = in_name_to_id("evdev:nub1");
159
160         scan_for_filters();
161
162         return 0;
163 }
164
165 void plat_finish(void)
166 {
167         plat_omap_finish();
168 }
169
170 static void apply_lcdrate(int pal)
171 {
172         char buf[128];
173
174         snprintf(buf, sizeof(buf), "%s/op_lcdrate.sh %d",
175                         pnd_script_base, pal ? 50 : 60);
176         system(buf);
177 }
178
179 static void apply_filter(int which)
180 {
181         char buf[128];
182         int i;
183
184         if (pnd_filter_list == NULL)
185                 return;
186
187         for (i = 0; i < which; i++)
188                 if (pnd_filter_list[i] == NULL)
189                         return;
190
191         if (pnd_filter_list[i] == NULL)
192                 return;
193
194         snprintf(buf, sizeof(buf), "%s/op_videofir.sh %s",
195                 pnd_script_base, pnd_filter_list[i]);
196         system(buf);
197 }
198
199 void plat_gvideo_open(int is_pal)
200 {
201         static int old_pal = -1, old_filter = -1;
202
203         if (is_pal != old_pal) {
204                 apply_lcdrate(is_pal);
205                 old_pal = is_pal;
206         }
207         if (filter != old_filter) {
208                 apply_filter(filter);
209                 old_filter = filter;
210         }
211
212         plat_omap_gvideo_open();
213 }
214
215 int plat_cpu_clock_get(void)
216 {
217         FILE *f;
218         int ret = 0;
219         f = fopen("/proc/pandora/cpu_mhz_max", "r");
220         if (f) {
221                 fscanf(f, "%d", &ret);
222                 fclose(f);
223         }
224         return ret;
225 }
226
227 int plat_cpu_clock_apply(int cpu_clock)
228 {
229         char buf[128];
230
231         if (cpu_clock != 0 && cpu_clock != plat_cpu_clock_get()) {
232                 snprintf(buf, sizeof(buf), "unset DISPLAY; echo y | %s/op_cpuspeed.sh %d",
233                          pnd_script_base, cpu_clock);
234                 system(buf);
235         }
236         return 0;
237 }
238
239 int plat_get_bat_capacity(void)
240 {
241         FILE *f;
242         int ret = 0;
243         f = fopen("/sys/class/power_supply/bq27500-0/capacity", "r");
244         if (f) {
245                 fscanf(f, "%d", &ret);
246                 fclose(f);
247         }
248         return ret;
249 }
250
251 void plat_step_volume(int is_up)
252 {
253 }
254
255 void plat_trigger_vibrate(int is_strong)
256 {
257 }
258