2d3fa877 |
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; |
e81b987f |
46 | const char **mfilters; |
2d3fa877 |
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 | |
a1b30e1a |
108 | plat_target.hwfilters = mfilters; |
2d3fa877 |
109 | } |
110 | |
a1b30e1a |
111 | static int do_system(const char *cmd) |
112 | { |
113 | int ret; |
114 | |
115 | ret = system(cmd); |
116 | if (ret >= 0) |
117 | ret = 0; |
118 | |
119 | return ret; |
120 | } |
121 | |
122 | static int read_int_from_file(const char *fname) |
123 | { |
124 | int ret = -1; |
125 | FILE *f; |
126 | |
127 | f = fopen(fname, "r"); |
128 | if (f) { |
129 | fscanf(f, "%d", &ret); |
130 | fclose(f); |
131 | } |
132 | return ret; |
133 | } |
134 | |
135 | static int lcdrate_set(int is_pal) |
2d3fa877 |
136 | { |
137 | static int old_pal = -1; |
138 | char buf[128]; |
139 | |
140 | if (is_pal == old_pal) |
a1b30e1a |
141 | return 0; |
142 | old_pal = is_pal; |
2d3fa877 |
143 | |
144 | snprintf(buf, sizeof(buf), "%s/op_lcdrate.sh %d", |
145 | pnd_script_base, is_pal ? 50 : 60); |
a1b30e1a |
146 | return do_system(buf); |
2d3fa877 |
147 | } |
148 | |
a1b30e1a |
149 | static int hwfilter_set(int which) |
2d3fa877 |
150 | { |
151 | static int old_filter = -1; |
152 | char buf[128]; |
153 | int i; |
154 | |
a1b30e1a |
155 | if (plat_target.hwfilters == NULL) |
156 | return -1; |
2d3fa877 |
157 | |
a1b30e1a |
158 | if (which == old_filter) |
159 | return 0; |
2d3fa877 |
160 | |
a1b30e1a |
161 | for (i = 0; i <= which; i++) |
162 | if (plat_target.hwfilters[i] == NULL) |
163 | return -1; |
2d3fa877 |
164 | |
2d3fa877 |
165 | old_filter = which; |
a1b30e1a |
166 | |
167 | snprintf(buf, sizeof(buf), "%s/op_videofir.sh %s", |
168 | pnd_script_base, plat_target.hwfilters[which]); |
169 | return do_system(buf); |
2d3fa877 |
170 | } |
171 | |
172 | static int cpu_clock_get(void) |
173 | { |
a1b30e1a |
174 | return read_int_from_file("/proc/pandora/cpu_mhz_max"); |
2d3fa877 |
175 | } |
176 | |
177 | static int cpu_clock_set(int cpu_clock) |
178 | { |
179 | char buf[128]; |
180 | |
a1b30e1a |
181 | if (cpu_clock < 14) |
182 | return -1; |
183 | |
184 | if (cpu_clock == cpu_clock_get()) |
185 | return 0; |
186 | |
187 | snprintf(buf, sizeof(buf), |
188 | "unset DISPLAY; echo y | %s/op_cpuspeed.sh %d", |
189 | pnd_script_base, cpu_clock); |
190 | return do_system(buf); |
2d3fa877 |
191 | } |
192 | |
a1b30e1a |
193 | static int bat_capacity_get(void) |
2d3fa877 |
194 | { |
a1b30e1a |
195 | return read_int_from_file("/sys/class/power_supply/bq27500-0/capacity"); |
196 | } |
197 | |
198 | static int gamma_set(int val, int black_level) |
199 | { |
200 | char buf[128]; |
201 | |
202 | snprintf(buf, sizeof(buf), "%s/op_gamma.sh -b %d %.2f", |
203 | pnd_script_base, black_level, (float)val / 100.0f); |
204 | return do_system(buf); |
2d3fa877 |
205 | } |
206 | |
1bc471eb |
207 | /* For now, this only switches tv-out to appropriate fb. |
208 | * Maybe this could control actual layers too? */ |
209 | static int switch_layer(int which, int enable) |
210 | { |
211 | static int was_ovl_enabled = -1; |
212 | int tv_enabled = 0; |
213 | char buf[128]; |
214 | int ret; |
215 | |
216 | if (which != 1) |
217 | return -1; |
218 | if (enable == was_ovl_enabled) |
219 | return 0; |
220 | |
221 | was_ovl_enabled = -1; |
222 | |
223 | tv_enabled = read_int_from_file( |
224 | "/sys/devices/platform/omapdss/display1/enabled"); |
225 | if (tv_enabled < 0) |
226 | return -1; |
227 | |
228 | if (!tv_enabled) { |
229 | // tv-out not enabled |
230 | return 0; |
231 | } |
232 | |
233 | snprintf(buf, sizeof(buf), "%s/op_tvout.sh -l %d", |
234 | pnd_script_base, enable); |
235 | ret = do_system(buf); |
236 | if (ret == 0) |
237 | was_ovl_enabled = enable; |
238 | |
239 | return ret; |
240 | } |
241 | |
2d3fa877 |
242 | struct plat_target plat_target = { |
243 | cpu_clock_get, |
244 | cpu_clock_set, |
a1b30e1a |
245 | bat_capacity_get, |
246 | hwfilter_set, |
247 | lcdrate_set, |
248 | gamma_set, |
1bc471eb |
249 | .switch_layer = switch_layer, |
2d3fa877 |
250 | }; |
251 | |
252 | int plat_target_init(void) |
253 | { |
254 | scan_for_filters(); |
255 | |
256 | return 0; |
257 | } |
258 | |
259 | /* to be called after in_probe */ |
260 | void plat_target_setup_input(void) |
261 | { |
262 | int gpiokeys_id; |
263 | |
264 | gpiokeys_id = in_name_to_id("evdev:gpio-keys"); |
265 | in_set_config(gpiokeys_id, IN_CFG_KEY_NAMES, |
266 | pandora_gpio_keys, sizeof(pandora_gpio_keys)); |
267 | in_set_config(gpiokeys_id, IN_CFG_DEFAULT_DEV, NULL, 0); |
268 | } |
269 | |
270 | void plat_target_finish(void) |
271 | { |
272 | } |