xref: /utopia/UTPA2-700.0.x/modules/usb/drv/usbhost/source/usb_hid_p1/drvhidcore.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 #if defined(MSOS_TYPE_NOS)
79 #include "MsVersion.h"
80 #include <stdio.h>
81 #include <string.h>
82 #include "../USBHostConfig.h"
83 #include "../../include/hal_arch.h"
84 #include "../../include/hal_cache.h"
85 
86 #include "../../include/datatype.h"
87 
88 #include "../../include/_drvUSB.h"
89 #include "../drvhid.h"
90 #include "../drvHostLib.h"
91 #include "../drvUsbMain.h"
92 
93 #include "MsCommon.h"
94 #include "MsIRQ.h"
95 #include "MsOS.h"
96 
97 #define USB_HID_DBG(x) // x;
98 #define USB_HID_MSG(x)  MS_CRITICAL_MSG(x)
99 #if 0
100 U8 code USBHID_P1_VBuf[32] = {'M', 'S', 'V', 'C', '0', '0',			    // 0, 0 fixed
101                         'U', '3',						            // Library ID
102 
103                         'A', '0', '0', '1', '0', '2',				// build number
104 
105                         '0', '0', '0', '0', '0', '0', '0', '0',		// change list 46058
106                         '0', '0', '0', '0', '0', '0', '0', '0', '0',// A4: Saturn, A:LG
107                         'T'};
108 #endif
109 
110 #define USB_HID_P1_DRV_VERSION                  /* Character String for DRV/API version             */  \
111     MSIF_TAG,                           /* 'MSIF'                                           */  \
112     MSIF_CLASS,                         /* '00'                                             */  \
113     MSIF_CUS,                           /* 0x0000                                           */  \
114     MSIF_MOD,                           /* 0x0000                                           */  \
115     MSIF_CHIP,                                                                                  \
116     MSIF_CPU,                                                                                   \
117     {'U','L','H','1'},                  /* IP__                                             */  \
118     {'0','1'},                          /* 0.0 ~ Z.Z                                        */  \
119     {'0','3'},                          /* 00 ~ 99                                          */  \
120     {'0','0','2','5','9','5','9','0'},  /* CL#                                              */  \
121     MSIF_OS
122 
123 static MSIF_Version _drv_usb_hid_p1_version = {
124     .DDI = { USB_HID_P1_DRV_VERSION },
125 };
126 
127 /*
128  * Read data value from item.
129  */
130 U8 UsbIntrData[16] __attribute__ ((aligned (16))) ;
131 U8 *pUsbIntrData;
132 extern UINT8  pUsbData[1024];
133 struct   axis_struct  axis[MAX_AXIS_NUM];
134 __u8     axis_idx;
135 struct   button_struct  buttons;
136 __u16  gOffsetBit;
137 
MDrv_USB_HID_GetLibVer(const MSIF_Version ** ppVersion)138 U8 MDrv_USB_HID_GetLibVer(const MSIF_Version **ppVersion)
139 {
140     if(!ppVersion)
141         return 1;
142 
143     *ppVersion = &_drv_usb_hid_p1_version;
144     return 0;
145 }
146 
item_udata(struct hid_item * item)147 __u32 item_udata(struct hid_item *item)
148 {
149 //    DO_PRINT("@@@ >>> Enter hid-core.c file --> item_udata function \n");
150 
151 	switch (item->size) {
152 		case 1: return item->zdata.u8;
153 		case 2: return item->zdata.u16;
154 		case 4: return item->zdata.u32;
155 	}
156 	return 0;
157 }
158 
item_sdata(struct hid_item * item)159 static  __s32 item_sdata(struct hid_item *item)
160 {
161     //DO_PRINT("@@@ >>> Enter hid-core.c file --> item_sdata function \n");
162 
163 	switch (item->size) {
164 		case 1: return item->zdata.s8;
165 		case 2: return item->zdata.s16;
166 		case 4: return item->zdata.s32;
167 	}
168 	return 0;
169 }
170 
171 
172 /*
173  * Parse a report description into a hid_device structure. Reports are
174  * enumerated, fields are attached to these reports.
175  */
176 
177 
fetch_item(__u8 * start,__u8 * end,struct hid_item * item)178 static __u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
179 {
180     //printf("@@@ >>> Enter hid-core.c file --> fetch_item function \n");
181 
182        //printf("start: %X, end: %X ", start, end);
183 	if ((end - start) > 0) {
184 
185 		__u8 b = *start++;
186              //printf("b:%02X ",b);
187 		item->type = (b >> 2) & 3;
188              //printf("type: %X ", item->type);
189 		item->tag  = (b >> 4) & 15;
190              //printf("tag:%02X ",item->tag);
191 
192 		if (item->tag == HID_ITEM_TAG_LONG) {
193 
194 			item->format = HID_ITEM_FORMAT_LONG;
195 
196 			if ((end - start) >= 2) {
197 
198 				item->size = *start++;
199 				item->tag  = *start++;
200 
201 				if ((end - start) >= item->size) {
202 					item->zdata.longdata = start;
203 					start += item->size;
204 					return start;
205 				}
206 			}
207 		} else {
208 
209 			item->format = HID_ITEM_FORMAT_SHORT;
210 			item->size = b & 3;
211                     //printf("size:%02X ",item->size);
212 			switch (item->size) {
213 
214 				case 0:
215                                   //printf("\n");
216 					return start;
217 
218 				case 1:
219 					if ((end - start) >= 1) {
220 						item->zdata.u8 = *start++;
221                                         //printf("U8:%02X\n",item->zdata.u8);
222                                         //  printf("return %x\n",(U16)start);
223 
224 						return start;
225 					}
226 					break;
227 
228 				case 2:
229 					if ((end - start) >= 2) {
230 						//item->zdata.u16 = *((__u16*)start);
231 						item->zdata.u16 = (((U16)*(start+1))<<8) | *start;
232                                         //printf("U16:%02X\n",item->zdata.u16);
233                                         start+=2;
234 						return start;
235 					}
236 					break;
237 
238 				case 3:
239 					item->size++;
240 					if ((end - start) >= 4) {
241 						//item->zdata.u32 = *((__u32*)start);
242 						item->zdata.u32 = (((U32)*(start+3))<<24) | (((U32)*(start+2))<<16) |
243 						                            (((U32)*(start+1))<<8) | *start;
244                                         //printf("U32:%02X\n",item->zdata.u32);
245                                         start+=4;
246 						return start;
247 					}
248 					break;
249 			}
250 		}
251 	}
252 	return NULL;
253 }
254 
open_collection(struct hid_parser * parser,unsigned type)255 static int open_collection(struct hid_parser *parser, unsigned type)
256 {
257 	struct hid_collection *collection;
258 	unsigned usage;
259 
260 	usage = parser->local.usage[0];
261 
262 	if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
263 		USB_HID_MSG(printf("collection stack overflow\n"););
264 		return -1;
265 	}
266 
267 	collection = parser->collection_stack + parser->collection_stack_ptr++;
268 	collection->type = type;
269 	collection->usage = usage;
270 
271 	return 0;
272 }
273 
close_collection(struct hid_parser * parser)274 static int close_collection(struct hid_parser *parser)
275 {
276 	if (!parser->collection_stack_ptr) {
277 		USB_HID_MSG(printf("collection stack underflow\n"););
278 		return -1;
279 	}
280 	parser->collection_stack_ptr--;
281 	return 0;
282 }
283 
hid_chk_variable(struct hid_parser * parser,unsigned report_type)284 static int hid_chk_variable(struct hid_parser *parser, unsigned report_type)
285 {
286     U8  ii, usg_count, rpt_count;
287 
288     usg_count = parser->local.usage_index;
289     rpt_count = parser->global.report_count;
290 
291     USB_HID_DBG(printf("hid_chk_variable: type: %X\n", report_type););
292     USB_HID_DBG(printf("usage count: %X, size: %X, count: %X\n",
293             usg_count, parser->global.report_size, rpt_count););
294 
295     if (parser->global.usage_page == USEAGE_PAGE_BUTTON)
296     {
297         buttons.startbit=gOffsetBit;
298         buttons.count=parser->global.report_size * rpt_count;
299         USB_HID_DBG(printf("Usage Page (buttons): %X size: %X\n", buttons.startbit, buttons.count););
300 
301         gOffsetBit+=buttons.count;
302         goto Func_Done;
303     }
304 
305     if (usg_count > 0)
306     {
307         for(ii=usg_count-rpt_count; ii<usg_count; ii++)
308         {
309             USB_HID_DBG(printf("local usage %X: %X\n", ii, parser->local.usage[ii]););
310             if (report_type == HID_INPUT_REPORT)
311             {
312                 if (parser->local.usage[ii] == USEAGE_X)
313                 {
314                      axis[axis_idx].startbit=gOffsetBit;
315                      axis[axis_idx].size=parser->global.report_size;
316                      axis[axis_idx].type=TYPE_AXIS_X;
317                      gOffsetBit+=axis[axis_idx].size;
318                      USB_HID_DBG(printf("Usage(X): %X, size: %X\n",axis[axis_idx].startbit, axis[axis_idx].size););
319 
320                      axis_idx++;
321                 }
322                 else if (parser->local.usage[ii] == USEAGE_Y)
323                 {
324                      axis[axis_idx].startbit=gOffsetBit;
325                      axis[axis_idx].size=parser->global.report_size;
326                      axis[axis_idx].type=TYPE_AXIS_Y;
327                      gOffsetBit+=axis[axis_idx].size;
328                      USB_HID_DBG(printf("Usage(Y): %X, size: %X\n",axis[axis_idx].startbit, axis[axis_idx].size););
329 
330                      axis_idx++;
331                 }
332                 else
333                 {
334                     USB_HID_DBG(printf("Unsupport usage: %X, size: %X\n", gOffsetBit, parser->global.report_size););
335                     gOffsetBit += parser->global.report_size;
336                 }
337             }
338             else
339             {
340                 USB_HID_DBG(printf("Unsupport usage: %X, size: %X\n", gOffsetBit, parser->global.report_size););
341                 gOffsetBit += parser->global.report_size;
342             }
343         }
344     }
345     else
346     {
347         USB_HID_DBG(printf("Unsupport data: %X, size: %X\n", gOffsetBit, parser->global.report_size * rpt_count););
348         gOffsetBit += parser->global.report_size * rpt_count;
349     }
350 
351 Func_Done:
352     return 0;
353 }
354 
355 /*
356  * Process a main item.
357  */
hid_parser_main(struct hid_parser * parser,struct hid_item * item)358  int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
359 {
360 	__u32 adata;
361 	int ret=0;
362 
363    // printf("  hid_parser_main   \n");
364 
365 	adata = item_udata(item);
366       // printf("TAG:%02bx\n",item->tag);
367 	switch (item->tag) {
368 		case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
369 #if 0
370                      if (adata==HID_COLLECTION_APPLICATION)
371                         {
372 				//printf("application\n");
373                             gOffsetBit=0;
374                             axis_idx=0;
375                             for (i=0 ; i < MAX_AXIS_NUM ; i ++)
376                             {
377                                 axis[i].size=0;
378                                 axis[i].val=0;
379                             }
380                         }
381 #endif
382 			ret = open_collection(parser, adata & 3);
383 			break;
384 		case HID_MAIN_ITEM_TAG_END_COLLECTION:
385 			ret = close_collection(parser);
386 			break;
387 		case HID_MAIN_ITEM_TAG_INPUT:
388                         ret = hid_chk_variable(parser, HID_INPUT_REPORT);
389 			//ret = hid_add_field(parser, HID_INPUT_REPORT, data);
390 			break;
391 		case HID_MAIN_ITEM_TAG_OUTPUT:
392                         ret = hid_chk_variable(parser, HID_OUTPUT_REPORT);
393 			//ret = hid_add_field(parser, HID_OUTPUT_REPORT, data);
394 			break;
395 		case HID_MAIN_ITEM_TAG_FEATURE:
396                         ret = hid_chk_variable(parser, HID_FEATURE_REPORT);
397 		//	ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
398 			break;
399 		default:
400 			//printf("unknown main item tag 0x%02bx", item->tag);
401 			ret = 0;
402 	}
403 
404 	memset(&parser->local, 0, sizeof(parser->local));	/* Reset the local parser environment */
405 
406 	return ret;
407 }
408 
409 
410 /*
411  * Process a global item.
412  */
413 
hid_parser_global(struct hid_parser * parser,struct hid_item * item)414  int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
415 {
416    // printf("  hid_parser_global   \n");
417 	switch (item->tag) {
418 
419 		case HID_GLOBAL_ITEM_TAG_PUSH:
420 
421 			//if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
422 			//	printf("global enviroment stack overflow");
423 				//return -1;
424 			//}
425 
426 			//memcpy(parser->global_stack + parser->global_stack_ptr++,
427 				//&parser->global, sizeof(struct hid_global));
428 			return 0;
429 
430 		case HID_GLOBAL_ITEM_TAG_POP:
431 
432 			//if (!parser->global_stack_ptr) {
433 			//	printf("global enviroment stack underflow");
434 			//	return -1;
435 			//}
436 
437 			//memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr,
438 				//sizeof(struct hid_global));
439 			return 0;
440 
441 		case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
442 			parser->global.usage_page = item_udata(item);
443 
444                     USB_HID_DBG(printf("Find a usage page: %lx\n", parser->global.usage_page););
445 #if 0
446                      if (parser->global.usage_page==USEAGE_PAGE_BUTTON)
447                         {
448                             buttons.startbit=gOffsetBit;
449                             printf("buttons start:%x\n",buttons.startbit);
450                             buttons.count=parser->global.report_count;
451                             printf("buttons count:%02bx\n",buttons.count);
452 
453                             gOffsetBit+=buttons.count;
454                         }
455 #endif
456 			return 0;
457 
458 		case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:
459 			parser->global.logical_minimum = item_sdata(item);
460 			return 0;
461 
462 		case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
463 			if (parser->global.logical_minimum < 0)
464 				parser->global.logical_maximum = item_sdata(item);
465 			else
466 				parser->global.logical_maximum = item_udata(item);
467 			return 0;
468 
469 		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
470 			parser->global.physical_minimum = item_sdata(item);
471 			return 0;
472 
473 		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
474 			if (parser->global.physical_minimum < 0)
475 				parser->global.physical_maximum = item_sdata(item);
476 			else
477 				parser->global.physical_maximum = item_udata(item);
478 			return 0;
479 
480 		case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
481 			parser->global.unit_exponent = item_udata(item);
482 			return 0;
483 
484 		case HID_GLOBAL_ITEM_TAG_UNIT:
485 			parser->global.unit = item_udata(item);
486 			return 0;
487 
488 		case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
489 			if ((parser->global.report_size = item_udata(item)) > 32) {
490 			//	printf("invalid report_size %d", parser->global.report_size);
491 				return -1;
492 			}
493 			return 0;
494 
495 		case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
496 			if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) {
497 				//printf("invalid report_count %d", parser->global.report_count);
498 				return -1;
499 			}
500 			return 0;
501 
502 		case HID_GLOBAL_ITEM_TAG_REPORT_ID:
503 			if ((parser->global.report_id = item_udata(item)) == 0) {
504 				//printf("report_id 0 is invalid");
505 				return -1;
506 			}
507 			return 0;
508 
509 		default:
510 			//printf("unknown global tag 0x%02bx", item->tag);
511 			return -1;
512 	}
513 }
514 
hid_parser_local(struct hid_parser * parser,struct hid_item * item)515  int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
516 {
517 	__u32 adata;
518 
519       //printf("  hid_parser_local   \n");
520 
521 	if (item->size == 0) {
522 		//printf("item data expected for local item");
523 		return -1;
524 	}
525 
526 	adata = item_udata(item);
527       //printf("local tag:%02bx\n",item->tag);
528 	switch (item->tag) {
529 
530 		case HID_LOCAL_ITEM_TAG_DELIMITER:
531 
532 			if (adata) {
533 				/*
534 				 * We treat items before the first delimiter
535 				 * as global to all usage sets (branch 0).
536 				 * In the moment we process only these global
537 				 * items and the first delimiter set.
538 				 */
539 				if (parser->local.delimiter_depth != 0) {
540 					//printf("nested delimiters");
541 					return -1;
542 				}
543 				parser->local.delimiter_depth++;
544 				parser->local.delimiter_branch++;
545 			} else {
546 				if (parser->local.delimiter_depth < 1) {
547 					//printf("bogus close delimiter");
548 					return -1;
549 				}
550 				parser->local.delimiter_depth--;
551 			}
552 			return 0;
553 
554 		case HID_LOCAL_ITEM_TAG_USAGE:
555 
556 			if (parser->local.delimiter_branch > 1) {
557 				//printf("alternative usage ignored");
558 				return 0;
559 			}
560 
561 			//if (item->size <= 2)
562 				//adata = (parser->global.usage_page << 16) + adata;
563 			USB_HID_DBG(printf("Find a usage: idx: %x, val: %lx\n", parser->local.usage_index, adata););
564                     parser->local.usage[parser->local.usage_index++] = adata;
565                   //   printf("useage:%lx\n",adata);
566 #if 0
567                      if (adata==USEAGE_X)
568                         {
569                              axis[axis_idx].startbit=gOffsetBit;
570                              axis[axis_idx].size=parser->global.report_size;
571                              axis[axis_idx].type=TYPE_AXIS_X;
572                              gOffsetBit+=axis[axis_idx].size;
573                              printf("Usage(X):%x\n",axis[axis_idx].startbit);
574 
575                              axis_idx++;
576                         }
577                      else if (adata==USEAGE_Y)
578                         {
579                              axis[axis_idx].startbit=gOffsetBit;
580                              axis[axis_idx].size=parser->global.report_size;
581                              axis[axis_idx].type=TYPE_AXIS_Y;
582                              gOffsetBit+=axis[axis_idx].size;
583                              printf("Usage(Y):%x\n",axis[axis_idx].startbit);
584 
585                              axis_idx++;
586                         }
587                      else if (adata==USEAGE_UNDEFINED)
588                         {
589                             printf("undefine usage :%02bx\n",parser->global.report_size);
590                             gOffsetBit+=parser->global.report_size;
591                         }
592 #endif
593 			return 0;// hid_add_usage(parser, data);
594 
595 		case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
596 
597 			if (parser->local.delimiter_branch > 1) {
598 				//printf("alternative usage ignored");
599 				return -1;
600 			}
601 
602 			if (item->size <= 2)
603 				adata = (parser->global.usage_page << 16) + adata;
604 
605 			parser->local.usage_minimum = adata;
606                     //  printf("logical minimum:%02bx\n",adata);
607 			return 0;
608 
609 		case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
610 
611 			if (parser->local.delimiter_branch > 1) {
612 				//printf("alternative usage ignored");
613 				return -1;
614 			}
615 
616 			if (item->size <= 2)
617 				adata = (parser->global.usage_page << 16) + adata;
618                     //  printf("logical maximum:%02bx\n",adata);
619 
620 			//for (n = parser->local.usage_minimum; n <= data; n++)
621 				//if (hid_add_usage(parser, n)) {
622 				//	printf("hid_add_usage failed\n");
623 				//	return -1;
624 				//}
625 			return 0;
626 
627 		default:
628 
629 			//printf("unknown local item tag 0x%x", item->tag);
630 			return -1;
631 	}
632 	return 0;
633 }
634 
hid_parse_report(__u8 * start,unsigned size)635 void hid_parse_report(__u8 *start, unsigned size)
636 {
637 	__u8 *end;
638        int result = 0;
639       struct hid_item xdata gitem;
640      struct hid_parser xdata gparser;
641 
642 
643   // printf("@@@ >>> Enter hid-core.c file --> hid_parse_report function \n");
644 
645 	memset((void*)&gparser, 0, sizeof(struct hid_parser));
646 	//parser->device = device;
647 
648 	end = start + size;
649 	while ((start = fetch_item(start, end, &gitem)) != 0)
650         {
651 
652 //            printf("gitem: start: %X, fmt: %X, size: %d, type: %X, tag: %X data: %X\n",
653 //                start, gitem.format, gitem.size, gitem.type, gitem.tag, gitem.zdata.u8);
654 
655 		if (gitem.format != HID_ITEM_FORMAT_SHORT)
656              {
657 			//printf("unexpected long global item");
658 			return ;
659 		}
660         if (gitem.type==0)
661             result=hid_parser_main(&gparser,&gitem);
662         else if (gitem.type==1)
663             result=hid_parser_global(&gparser,&gitem);
664         else if (gitem.type==2)
665             result=hid_parser_local(&gparser,&gitem);
666 
667 		if (result)
668              {
669 			//printf("item %u %u %u %u parsing failed\n",
670 				//gitem.format, (unsigned)gitem.size, (unsigned)gitem.type, (unsigned)gitem.tag);
671 			//hid_free_device(device);
672 			//kfree(parser);
673 			return ;
674 		}
675 
676 		if (start == end) {
677 		//	if (parser.collection_stack_ptr) {
678 				//printf("unbalanced collection at end of report description");
679 				//return ;
680 			//}
681 			if (gparser.local.delimiter_depth) {
682 				//printf("unbalanced delimiter at end of report description");
683 				return ;
684 			}
685 			return;
686 		}
687 	}
688 
689 	//printf("item fetching failed at offset %d\n", (int)(end - start));
690 	return;
691 }
Parse_Joystick_Report(__u8 * report)692 U16 Parse_Joystick_Report(__u8 *report)
693 {
694 __u8 i,tmp;
695 __u16  tmp2,result;
696  //printf("t1");
697 
698          //   for (i=0 ; i < 8 ; i++)
699 		//printf("%02bx ", report[i]);
700             for (i=0 ; i < MAX_AXIS_NUM ; i ++)
701            {
702                if (axis[i].size)                //this AXIS exist
703                 {
704                         tmp=GetValue(report,axis[i].startbit,axis[i].size);
705                         if (axis[i].val!=tmp )
706                             {
707                                  USB_HID_DBG(printf(" axis idx %bx, offset:%x ,val %02bx  tmp:%02bx\n", i,axis[i].startbit,axis[i].val,tmp));
708                                  axis[i].val=tmp;
709                                  result=(axis[i].type << 12) | tmp;
710                                  return result;
711 
712                             }
713                 }
714 
715             }
716 // printf("t2");
717 		//printf("button start:%x",buttons.startbit);
718             tmp2=GetValue(report,buttons.startbit,buttons.count);
719            // printf("tmp2:%x\n",tmp2);
720             if (buttons.val!=tmp2)
721                 {
722                     USB_HID_DBG(printf("buttons:%x %x\n",buttons.val, tmp2));
723                     buttons.val=tmp2;
724                     tmp2 &=0x0fff;              //only maximum 12 bits allowed
725                     result=(TYPE_BUTTON << 12) | tmp2;
726                     return result;
727 
728                 }
729       return 0;         //no event
730 }
GetValue(__u8 * buf,__u16 offset,__u8 size)731 __u32 GetValue(__u8 *buf, __u16 offset,__u8 size)
732 {
733 
734         __u8 *ptr;
735         __u32  x,y;
736         __u8 i;
737 
738         ptr=buf+offset/8;
739         x= *ptr + (*(ptr+1)<<8) + (*(ptr+2)<< 16) + (*(ptr+3) <<24);
740         x>>=offset % 8;
741         y=0;
742         for (i=0 ; i < size ; i++)
743        {
744             y=y << 1;
745             y|=1;
746 
747        }
748         x= x & y;       //mask unwanted bits
749         return x;
750 }
751 code UINT8  GET_REPORT_DESCRIPTOR[]        = {0x81,0x06,0x00,0x22,0x00,0x00,0x65,0x00};
752 
GetReportDescriptor(void)753 BOOLEAN GetReportDescriptor(void)
754 {
755     UINT8 bCMD[8];
756     UINT8 i;
757 
758    memcpy(bCMD,GET_REPORT_DESCRIPTOR,8);
759    if ( flib_Host20_Issue_Control (1,bCMD,0x65,pUsbData)>0)
760        return FALSE;
761 
762     gOffsetBit=0;
763     axis_idx=0;
764     for (i=0 ; i < MAX_AXIS_NUM ; i++)
765     {
766         axis[i].size=0;
767         axis[i].val=0;
768     }
769 
770     buttons.count = 0;
771     buttons.startbit = 0;
772     buttons.val = 0;
773 
774    hid_parse_report(pUsbData, 0x65);
775 
776    return TRUE;
777 
778 }
drvUSBHost_HID_Initial(void)779 U8 drvUSBHost_HID_Initial(void)
780 {
781     USB_HID_DBG(printf("HID device\n"););
782 
783     GetReportDescriptor();
784 
785     pUsbIntrData=(U8*) KSEG02KSEG1(UsbIntrData);
786     MY_HAL_DCACHE_FLUSH((U32)UsbIntrData, 16);
787     flib_Host20_Interrupt_Init(3);
788 
789     return 0;
790 }
MDrv_GET_JOYSTICK_STATUS(void)791 U16  MDrv_GET_JOYSTICK_STATUS(void)
792 {
793     __u16 tmp=0;
794 
795     //printf("x1");
796 
797     memset(pUsbIntrData, 0, 8);
798      if (flib_Host20_Issue_Interrupt((U32)pUsbIntrData,8)==HOST20_OK)
799          tmp=Parse_Joystick_Report(pUsbIntrData);
800 // printf("x3");
801 
802      return tmp;
803 }
804 
805 U8  ReportData[8];
MDrv_Get_HID_Report_Raw_Data(void)806 U8*  MDrv_Get_HID_Report_Raw_Data(void)
807 {
808     U8  i;
809 
810     memset(ReportData, 0, 8);
811     if (flib_Host20_Issue_Interrupt((U32)pUsbIntrData,8)==HOST20_OK)
812     {
813         for (i=0 ; i <8 ; i++)
814         {
815             ReportData[i]=pUsbIntrData[i];
816             // printf("%02bx ",ReportData[i]);
817         }
818     }
819 
820     return ReportData;
821 }
822 
823 #endif //#if defined(MSOS_TYPE_NOS)
824 
825