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