Added my own evdev handler for dpad/dpadbuttons/nubs, works fantastic
[pandora-libraries.git] / lib / pnd_io_gpio.c
1
2 // this is pulled from cpasjuste and/or pickle
3
4 #if defined (_PANDORA) || !defined (EMULATOR)
5
6 /* cribbed from pnd_keytypes.h so as to make it unnecessary */
7   #define BITS_PER_LONG (sizeof(long) * 8)
8   #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
9   #include <string.h>
10   #include <fcntl.h>
11   #include <unistd.h>
12   #include <stdio.h>
13 /* back to reality */
14
15 #include <stdlib.h> /* abs() */
16 #include <linux/input.h> /* struct input_event */
17
18 #include "pnd_io_gpio.h"
19 //#include "pnd_keytype.h"
20
21 unsigned char GLES2D_Pad [ pke_pad_max ];
22
23 char event_name[30];
24 int fd_usbk, fd_usbm, fd_gpio, fd_pndk, fd_nub1, fd_nub2, fd_ts, rd, i, j, k;
25 struct input_event ev[64];
26 int version;
27 unsigned short id[4];
28 unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
29 char dev_name[256] = "Unknown";
30 int absolute[5];
31
32 char pnd_nub1[9]  = "vsense66";
33 char pnd_nub2[9]  = "vsense67";
34 char pnd_key[19]  = "omap_twl4030keypad";
35 char pnd_gpio[10] = "gpio-keys";
36
37 #define DEV_NUB1 0
38 #define DEV_NUB2 1
39 #define DEV_PNDK 2
40 #define DEV_GPIO 3
41
42 #define NUB1_CUTOFF 100
43 #define NUB2_CUTOFF 100
44 #define NUB2_SCALE  10
45
46 void PND_Setup_Controls ( void ) {
47   //printf( "Setting up Pandora Controls\n" );
48
49   // Static Controls
50   // Pandora keyboard
51   fd_pndk = PND_OpenEventDeviceByName(pnd_key);
52   // Pandora buttons
53   fd_gpio = PND_OpenEventDeviceByName(pnd_gpio);
54   // Pandora analog nub's
55   fd_nub1 = PND_OpenEventDeviceByName(pnd_nub1);
56   fd_nub2 = PND_OpenEventDeviceByName(pnd_nub2);
57
58 }
59
60 void PND_Close_Controls ( void ) {
61   //printf( "Closing Pandora Controls\n" );
62
63   if( fd_pndk > 0 )
64     close(fd_pndk );
65   if( fd_gpio > 0 )
66     close(fd_gpio );
67   if( fd_nub1 > 0 )
68     close(fd_nub1 );
69   if( fd_nub2 > 0 )
70     close(fd_nub2 );
71
72 }
73
74 void PND_SendKeyEvents ( void ) {
75   PND_ReadEvents( fd_pndk, DEV_PNDK );
76   PND_ReadEvents( fd_gpio, DEV_GPIO );
77   PND_ReadEvents( fd_nub1, DEV_NUB1 );
78   PND_ReadEvents( fd_nub2, DEV_NUB2 );
79 }
80
81 void PND_ReadEvents ( int fd, int device ) {
82
83   if ( fd != 0 ) {
84
85     rd = read ( fd, ev, sizeof(struct input_event) * 64 );
86
87     if ( rd > (int) sizeof(struct input_event) ) {
88       for (i = 0; i < rd / sizeof(struct input_event); i++) {
89         PND_CheckEvent ( &ev[i], device );
90       }
91     }
92   
93   } // got fd?
94
95   return;
96 }
97
98 void PND_CheckEvent ( struct input_event *event, int device ) {
99   int value;
100
101   // printf( "Device %d Type %d Code %d Value %d\n", device, event->type, event->code, event->value );
102
103   value = event->value;
104
105   switch( event->type ) {
106
107   case EV_KEY:
108
109     switch( event->code ) {
110
111     case KEY_UP:
112       if ( event->value ) {     
113         GLES2D_Pad[pke_pad_up] = 1;
114       } else {
115         GLES2D_Pad[pke_pad_up] = 0;
116       }
117       break;
118
119     case KEY_DOWN:
120       if ( event->value ) {     
121         GLES2D_Pad[pke_pad_down] = 1;
122       } else {
123         GLES2D_Pad[pke_pad_down] = 0;
124       }
125       break;
126
127     case KEY_LEFT:
128       if ( event->value ) {     
129         GLES2D_Pad[pke_pad_left] = 1;
130       } else {
131         GLES2D_Pad[pke_pad_left] = 0;
132       }
133       break;
134
135     case KEY_RIGHT:
136       if ( event->value ) {     
137         GLES2D_Pad[pke_pad_right] = 1;
138       } else {
139         GLES2D_Pad[pke_pad_right] = 0;
140       }
141       break;
142
143     case KEY_MENU:
144       if ( event->value ) {     
145         GLES2D_Pad[pke_pad_menu] = 1;
146       } else {
147         GLES2D_Pad[pke_pad_menu] = 0;
148       }
149       break;
150
151     case BTN_START:
152       if ( event->value ) printf("START\n");
153       break;
154
155     case BTN_SELECT:
156       if ( event->value ) printf("SELECT\n");
157       break;
158
159     case BTN_X:
160       if ( event->value ) {     
161         GLES2D_Pad[pke_pad_x] = 1;
162       } else {
163         GLES2D_Pad[pke_pad_x] = 0;
164       }
165       break;
166
167     case BTN_Y:
168       if ( event->value ) {     
169         GLES2D_Pad[pke_pad_y] = 1;
170       } else {
171         GLES2D_Pad[pke_pad_y] = 0;
172       }
173       break;
174
175     case BTN_A:
176       if ( event->value ) {     
177         GLES2D_Pad[pke_pad_a] = 1;
178       } else {
179         GLES2D_Pad[pke_pad_a] = 0;
180       }
181       break;
182
183     case BTN_B:
184       if ( event->value ) {     
185         GLES2D_Pad[pke_pad_b] = 1;
186       } else {
187         GLES2D_Pad[pke_pad_b] = 0;
188       }
189       break;
190
191     case BTN_TL:
192       if ( event->value ) {     
193         GLES2D_Pad[pke_pad_l] = 1;
194       } else {
195         GLES2D_Pad[pke_pad_l] = 0;
196       }
197       break;
198
199     case BTN_TR:
200       if ( event->value ) {     
201         GLES2D_Pad[pke_pad_r] = 1;
202       } else {
203         GLES2D_Pad[pke_pad_r] = 0;
204       }
205       break;
206
207     default:
208       break;
209     }
210     break;
211     
212   case EV_ABS:
213
214     switch ( device ) {
215
216     case DEV_NUB1:
217       if ( event->code == ABS_X ) {
218         //printf( "nub1 x %3d\n", value );
219         if( abs(value) > NUB1_CUTOFF ) {
220           if( value > 0 ) {
221             value = 1;
222           } else if( value < 0 ) {
223             value = 1;                                              
224           }
225         } else {
226         }
227       }
228         
229       if( event->code == ABS_Y ) {
230         //printf( "nub1 y %3d\n", value );
231         if( abs(value) > NUB1_CUTOFF ) {
232           if( value > 0 ) {
233             value = 1;
234           } else if( value < 0 ) {
235             value = 1;
236           }
237         } else {
238         }
239       }
240       break;
241
242     case DEV_NUB2:
243       if(event->code == ABS_X) {
244         //printf( "nub2 x %3d\n", value );
245         if( abs(value) > NUB2_CUTOFF ) {
246           if( value > 0 ) {
247             value = 1;
248           } else if( value < 0 ) {
249             value = 1;                                              
250           }
251         } else {
252         }
253       }
254         
255       if(event->code == ABS_Y) {
256         //printf( "nub2 y %3d\n", value );
257         if( abs(value) > NUB2_CUTOFF ) {
258           if( value > 0 ) {
259             value = 1;
260           } else if( value < 0 ) {
261             value = 1;
262           }
263         } else {
264         }
265       }
266       break;
267
268     }
269     break;
270   }
271
272   return;
273 }
274
275 int PND_OpenEventDeviceByID ( int event_id ) {
276   int fd;
277
278   snprintf( event_name, sizeof(event_name), "/dev/input/event%d", event_id );
279   printf( "Device: %s\n", event_name );
280   if ((fd = open(event_name, O_RDONLY |  O_NDELAY)) < 0) {
281     perror("ERROR: Could not open device");
282     return 0;
283   }
284
285   if (ioctl(fd, EVIOCGVERSION, &version)) {
286     perror("evtest: can't get version");
287     return 0;
288   }
289
290   printf("Input driver version is %d.%d.%d\n",
291          version >> 16, (version >> 8) & 0xff, version & 0xff);
292
293   ioctl(fd, EVIOCGID, id);
294   printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
295          id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);
296
297   ioctl(fd, EVIOCGNAME(sizeof(dev_name)), dev_name);
298   printf("Input device name: \"%s\"\n", dev_name);
299
300   return fd;
301 }
302
303 int PND_OpenEventDeviceByName ( char device_name[] ) {
304   int fd;
305
306   for (i = 0; 1; i++) {
307
308     snprintf( event_name, sizeof(event_name), "/dev/input/event%d", i );
309     printf( "Device: %s\n", event_name );
310     if ((fd = open(event_name, O_RDONLY |  O_NDELAY)) < 0) {
311       perror("ERROR: Could not open device");
312       return 0;
313     }
314
315     if (fd < 0) break; /* no more devices */
316
317     ioctl(fd, EVIOCGNAME(sizeof(dev_name)), dev_name);
318     if (strcmp(dev_name, device_name) == 0) {
319
320       if (ioctl(fd, EVIOCGVERSION, &version)) {
321         perror("evtest: can't get version");
322         return 0;
323       }
324
325       printf("Input driver version is %d.%d.%d\n",
326              version >> 16, (version >> 8) & 0xff, version & 0xff);
327
328       ioctl(fd, EVIOCGID, id);
329       printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
330              id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);
331
332       ioctl(fd, EVIOCGNAME(sizeof(dev_name)), dev_name);
333       printf("Input device name: \"%s\"\n", dev_name);
334                   
335       return fd;
336     }
337
338     close(fd); /* we don't need this device */
339   }
340
341   return 0;
342 }
343
344 int PND_Pad_RecentlyPressed ( pnd_keytype_e num ) {
345   static int GLES2D_Pad_old [ pke_pad_max ];
346
347   if ( !GLES2D_Pad_old[num] && GLES2D_Pad[num] ) {
348     GLES2D_Pad_old[num] = GLES2D_Pad[num];
349     return 1;
350   }
351
352   GLES2D_Pad_old[num] = GLES2D_Pad[num];
353
354   return 0;
355 }
356
357 #endif