add pandora code from PCSX
[libpicofe.git] / pandora / plat.c
1 /*
2  * (C) GraÅžvydas "notaz" Ignotas, 2011,2012
3  *
4  * This work is licensed under the terms of any of these licenses
5  * (at your option):
6  *  - GNU GPL, version 2 or later.
7  *  - GNU LGPL, version 2.1 or later.
8  *  - MAME license.
9  * See the COPYING file in the top-level directory.
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/types.h>
16 #include <dirent.h>
17 #include <linux/input.h>
18 #include <errno.h>
19
20 #include "../plat.h"
21 #include "../input.h"
22
23 static const char * const pandora_gpio_keys[KEY_MAX + 1] = {
24         [0 ... KEY_MAX] = NULL,
25         [KEY_UP]        = "Up",
26         [KEY_LEFT]      = "Left",
27         [KEY_RIGHT]     = "Right",
28         [KEY_DOWN]      = "Down",
29         [KEY_HOME]      = "(A)",
30         [KEY_PAGEDOWN]  = "(X)",
31         [KEY_END]       = "(B)",
32         [KEY_PAGEUP]    = "(Y)",
33         [KEY_RIGHTSHIFT]= "(L)",
34         [KEY_RIGHTCTRL] = "(R)",
35         [KEY_LEFTALT]   = "Start",
36         [KEY_LEFTCTRL]  = "Select",
37         [KEY_MENU]      = "Pandora",
38 };
39
40 static const char pnd_script_base[] = "sudo -n /usr/pandora/scripts";
41
42 static void scan_for_filters(void)
43 {
44         struct dirent *ent;
45         int i, count = 0;
46         char **mfilters;
47         char buff[64];
48         DIR *dir;
49
50         dir = opendir("/etc/pandora/conf/dss_fir");
51         if (dir == NULL) {
52                 perror("filter opendir");
53                 return;
54         }
55
56         while (1) {
57                 errno = 0;
58                 ent = readdir(dir);
59                 if (ent == NULL) {
60                         if (errno != 0)
61                                 perror("readdir");
62                         break;
63                 }
64
65                 if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
66                         continue;
67
68                 count++;
69         }
70
71         if (count == 0)
72                 return;
73
74         mfilters = calloc(count + 1, sizeof(mfilters[0]));
75         if (mfilters == NULL)
76                 return;
77
78         rewinddir(dir);
79         for (i = 0; (ent = readdir(dir)); ) {
80                 size_t len;
81
82                 if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
83                         continue;
84
85                 len = strlen(ent->d_name);
86
87                 // skip pre-HF5 extra files
88                 if (len >= 3 && strcmp(ent->d_name + len - 3, "_v3") == 0)
89                         continue;
90                 if (len >= 3 && strcmp(ent->d_name + len - 3, "_v5") == 0)
91                         continue;
92
93                 // have to cut "_up_h" for pre-HF5
94                 if (len > 5 && strcmp(ent->d_name + len - 5, "_up_h") == 0)
95                         len -= 5;
96
97                 if (len > sizeof(buff) - 1)
98                         continue;
99
100                 strncpy(buff, ent->d_name, len);
101                 buff[len] = 0;
102                 mfilters[i] = strdup(buff);
103                 if (mfilters[i] != NULL)
104                         i++;
105         }
106         closedir(dir);
107
108         plat_target.filters = mfilters;
109 }
110
111 static void set_lcdrate(int is_pal)
112 {
113         static int old_pal = -1;
114         char buf[128];
115
116         if (is_pal == old_pal)
117                 return;
118
119         snprintf(buf, sizeof(buf), "%s/op_lcdrate.sh %d",
120                         pnd_script_base, is_pal ? 50 : 60);
121         system(buf);
122         old_pal = is_pal;
123 }
124
125 static void set_filter(int which)
126 {
127         static int old_filter = -1;
128         char buf[128];
129         int i;
130
131         if (plat_target.filters == NULL || which == old_filter)
132                 return;
133
134         for (i = 0; i < which; i++)
135                 if (plat_target.filters[i] == NULL)
136                         return;
137
138         if (plat_target.filters[i] == NULL)
139                 return;
140
141         snprintf(buf, sizeof(buf), "%s/op_videofir.sh %s",
142                 pnd_script_base, plat_target.filters[i]);
143         system(buf);
144         old_filter = which;
145 }
146
147 static int cpu_clock_get(void)
148 {
149         FILE *f;
150         int ret = 0;
151         f = fopen("/proc/pandora/cpu_mhz_max", "r");
152         if (f) {
153                 fscanf(f, "%d", &ret);
154                 fclose(f);
155         }
156         return ret;
157 }
158
159 static int cpu_clock_set(int cpu_clock)
160 {
161         char buf[128];
162
163         if (cpu_clock != 0 && cpu_clock != cpu_clock_get()) {
164                 snprintf(buf, sizeof(buf), "unset DISPLAY; echo y | %s/op_cpuspeed.sh %d",
165                          pnd_script_base, cpu_clock);
166                 system(buf);
167         }
168         return 0;
169 }
170
171 static int get_bat_capacity(void)
172 {
173         FILE *f;
174         int ret = 0;
175         f = fopen("/sys/class/power_supply/bq27500-0/capacity", "r");
176         if (f) {
177                 fscanf(f, "%d", &ret);
178                 fclose(f);
179         }
180         return ret;
181 }
182
183 struct plat_target plat_target = {
184         cpu_clock_get,
185         cpu_clock_set,
186         get_bat_capacity,
187         set_filter,
188         NULL,
189         set_lcdrate,
190 };
191
192 int plat_target_init(void)
193 {
194         scan_for_filters();
195
196         return 0;
197 }
198
199 /* to be called after in_probe */
200 void plat_target_setup_input(void)
201 {
202         int gpiokeys_id;
203
204         gpiokeys_id = in_name_to_id("evdev:gpio-keys");
205         in_set_config(gpiokeys_id, IN_CFG_KEY_NAMES,
206                       pandora_gpio_keys, sizeof(pandora_gpio_keys));
207         in_set_config(gpiokeys_id, IN_CFG_DEFAULT_DEV, NULL, 0);
208 }
209
210 void plat_target_finish(void)
211 {
212 }