xref: /utopia/UTPA2-700.0.x/modules/usb/drv/usbhost/source3/usb_hid_p3/drvhidcore_3.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_3.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_3.h"
90 #include "../drvHostLib_3.h"
91 #include "../drvUsbMain_3.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 
100 #if 0
101 U8 code USBHID_P3_VBuf[32] = {'M', 'S', 'V', 'C', '0', '0',			    // 0, 0 fixed
102                         'U', '3',						            // Library ID
103 
104                         'A', '0', '0', '1', '0', '2',				// build number
105 
106                         '0', '0', '0', '0', '0', '0', '0', '0',		// change list 46058
107                         '0', '0', '0', '0', '0', '0', '0', '0', '0',// A4: Saturn, A:LG
108                         'T'};
109 #endif
110 
111 #define USB_HID_P3_DRV_VERSION                  /* Character String for DRV/API version             */  \
112     MSIF_TAG,                           /* 'MSIF'                                           */  \
113     MSIF_CLASS,                         /* '00'                                             */  \
114     MSIF_CUS,                           /* 0x0000                                           */  \
115     MSIF_MOD,                           /* 0x0000                                           */  \
116     MSIF_CHIP,                                                                                  \
117     MSIF_CPU,                                                                                   \
118     {'U','L','H','3'},                  /* IP__                                             */  \
119     {'0','1'},                          /* 0.0 ~ Z.Z                                        */  \
120     {'0','3'},                          /* 00 ~ 99                                          */  \
121     {'0','0','2','5','9','5','9','0'},  /* CL#                                              */  \
122     MSIF_OS
123 
124 static MSIF_Version _drv_usb_hid_p3_version = {
125     .DDI = { USB_HID_P3_DRV_VERSION },
126 };
127 
128 /*
129  * Read data value from item.
130  */
131 U8 UsbIntrData_Port3[16] __attribute__ ((aligned (16))) ;
132 U8 *pUsbIntrData_Port3;
133 extern UINT8  pUsbData_Port3[1024];
134 struct   axis_struct  axis_Port3[MAX_AXIS_NUM];
135 __u8     axis_idx_Port3;
136 struct   button_struct  buttons_Port3;
137 __u16  gOffsetBit_Port3;
138 
MDrv_USB_HID_GetLibVer_Port3(const MSIF_Version ** ppVersion)139 U8 MDrv_USB_HID_GetLibVer_Port3(const MSIF_Version **ppVersion)
140 {
141     if(!ppVersion)
142         return 1;
143 
144     *ppVersion = &_drv_usb_hid_p3_version;
145     return 0;
146 }
147 
item_udata_Port3(struct hid_item * item)148 __u32 item_udata_Port3(struct hid_item *item)
149 {
150 //    DO_PRINT("@@@ >>> Enter hid-core.c file --> item_udata function \n");
151 
152 	switch (item->size) {
153 		case 1: return item->zdata.u8;
154 		case 2: return item->zdata.u16;
155 		case 4: return item->zdata.u32;
156 	}
157 	return 0;
158 }
159 
item_sdata_Port3(struct hid_item * item)160 static  __s32 item_sdata_Port3(struct hid_item *item)
161 {
162     //DO_PRINT("@@@ >>> Enter hid-core.c file --> item_sdata function \n");
163 
164 	switch (item->size) {
165 		case 1: return item->zdata.s8;
166 		case 2: return item->zdata.s16;
167 		case 4: return item->zdata.s32;
168 	}
169 	return 0;
170 }
171 
172 
173 /*
174  * Parse a report description into a hid_device structure. Reports are
175  * enumerated, fields are attached to these reports.
176  */
177 
178 
fetch_item_Port3(__u8 * start,__u8 * end,struct hid_item * item)179 static __u8 *fetch_item_Port3(__u8 *start, __u8 *end, struct hid_item *item)
180 {
181     //printf("@@@ >>> Enter hid-core.c file --> fetch_item function \n");
182 
183        //printf("start: %X, end: %X ", start, end);
184 	if ((end - start) > 0) {
185 
186 		__u8 b = *start++;
187              //printf("b:%02X ",b);
188 		item->type = (b >> 2) & 3;
189              //printf("type: %X ", item->type);
190 		item->tag  = (b >> 4) & 15;
191              //printf("tag:%02X ",item->tag);
192 
193 		if (item->tag == HID_ITEM_TAG_LONG) {
194 
195 			item->format = HID_ITEM_FORMAT_LONG;
196 
197 			if ((end - start) >= 2) {
198 
199 				item->size = *start++;
200 				item->tag  = *start++;
201 
202 				if ((end - start) >= item->size) {
203 					item->zdata.longdata = start;
204 					start += item->size;
205 					return start;
206 				}
207 			}
208 		} else {
209 
210 			item->format = HID_ITEM_FORMAT_SHORT;
211 			item->size = b & 3;
212                     //printf("size:%02X ",item->size);
213 			switch (item->size) {
214 
215 				case 0:
216                                   //printf("\n");
217 					return start;
218 
219 				case 1:
220 					if ((end - start) >= 1) {
221 						item->zdata.u8 = *start++;
222                                         //printf("U8:%02X\n",item->zdata.u8);
223                                         //  printf("return %x\n",(U16)start);
224 
225 						return start;
226 					}
227 					break;
228 
229 				case 2:
230 					if ((end - start) >= 2) {
231 						//item->zdata.u16 = *((__u16*)start);
232 						item->zdata.u16 = (((U16)*(start+1))<<8) | *start;
233                                         //printf("U16:%02X\n",item->zdata.u16);
234                                         start+=2;
235 						return start;
236 					}
237 					break;
238 
239 				case 3:
240 					item->size++;
241 					if ((end - start) >= 4) {
242 						//item->zdata.u32 = *((__u32*)start);
243 						item->zdata.u32 = (((U32)*(start+3))<<24) | (((U32)*(start+2))<<16) |
244 						                            (((U32)*(start+1))<<8) | *start;
245                                         //printf("U32:%02X\n",item->zdata.u32);
246                                         start+=4;
247 						return start;
248 					}
249 					break;
250 			}
251 		}
252 	}
253 	return NULL;
254 }
255 
open_collection_Port3(struct hid_parser * parser,unsigned type)256 static int open_collection_Port3(struct hid_parser *parser, unsigned type)
257 {
258 	struct hid_collection *collection;
259 	unsigned usage;
260 
261 	usage = parser->local.usage[0];
262 
263 	if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
264 		USB_HID_MSG(printf("collection stack overflow\n"));
265 		return -1;
266 	}
267 
268 	collection = parser->collection_stack + parser->collection_stack_ptr++;
269 	collection->type = type;
270 	collection->usage = usage;
271 
272 	return 0;
273 }
274 
close_collection_Port3(struct hid_parser * parser)275 static int close_collection_Port3(struct hid_parser *parser)
276 {
277 	if (!parser->collection_stack_ptr) {
278 		USB_HID_MSG(printf("collection stack underflow\n"));
279 		return -1;
280 	}
281 	parser->collection_stack_ptr--;
282 	return 0;
283 }
284 
hid_chk_variable_Port3(struct hid_parser * parser,unsigned report_type)285 static int hid_chk_variable_Port3(struct hid_parser *parser, unsigned report_type)
286 {
287     U8  ii, usg_count, rpt_count;
288 
289     usg_count = parser->local.usage_index;
290     rpt_count = parser->global.report_count;
291 
292     USB_HID_DBG(printf("hid_chk_variable: type: %X\n", report_type));
293     USB_HID_DBG(printf("usage count: %X, size: %X, count: %X\n",
294             usg_count, parser->global.report_size, rpt_count));
295 
296     if (parser->global.usage_page == USEAGE_PAGE_BUTTON)
297     {
298         buttons_Port3.startbit=gOffsetBit_Port3;
299         buttons_Port3.count=parser->global.report_size * rpt_count;
300         USB_HID_DBG(printf("Usage Page (buttons): %X size: %X\n", buttons_Port3.startbit, buttons_Port3.count));
301 
302         gOffsetBit_Port3+=buttons_Port3.count;
303         goto Func_Done;
304     }
305 
306     if (usg_count > 0)
307     {
308         for(ii=usg_count-rpt_count; ii<usg_count; ii++)
309         {
310             USB_HID_DBG(printf("local usage %X: %X\n", ii, parser->local.usage[ii]));
311             if (report_type == HID_INPUT_REPORT)
312             {
313                 if (parser->local.usage[ii] == USEAGE_X)
314                 {
315                      axis_Port3[axis_idx_Port3].startbit=gOffsetBit_Port3;
316                      axis_Port3[axis_idx_Port3].size=parser->global.report_size;
317                      axis_Port3[axis_idx_Port3].type=TYPE_AXIS_X;
318                      gOffsetBit_Port3+=axis_Port3[axis_idx_Port3].size;
319                      USB_HID_DBG(printf("Usage(X): %X, size: %X\n",axis_Port3[axis_idx_Port3].startbit, axis_Port3[axis_idx_Port3].size));
320 
321                      axis_idx_Port3++;
322                 }
323                 else if (parser->local.usage[ii] == USEAGE_Y)
324                 {
325                      axis_Port3[axis_idx_Port3].startbit=gOffsetBit_Port3;
326                      axis_Port3[axis_idx_Port3].size=parser->global.report_size;
327                      axis_Port3[axis_idx_Port3].type=TYPE_AXIS_Y;
328                      gOffsetBit_Port3+=axis_Port3[axis_idx_Port3].size;
329                      USB_HID_DBG(printf("Usage(Y): %X, size: %X\n",axis_Port3[axis_idx_Port3].startbit, axis_Port3[axis_idx_Port3].size));
330 
331                      axis_idx_Port3++;
332                 }
333                 else
334                 {
335                     USB_HID_DBG(printf("Unsupport usage: %X, size: %X\n", gOffsetBit_Port3, parser->global.report_size));
336                     gOffsetBit_Port3+= parser->global.report_size;
337                 }
338             }
339             else
340             {
341                 USB_HID_DBG(printf("Unsupport usage: %X, size: %X\n", gOffsetBit_Port3, parser->global.report_size));
342                 gOffsetBit_Port3 += parser->global.report_size;
343             }
344         }
345     }
346     else
347     {
348         USB_HID_DBG(printf("Unsupport data: %X, size: %X\n", gOffsetBit_Port3, parser->global.report_size * rpt_count));
349         gOffsetBit_Port3 += parser->global.report_size * rpt_count;
350     }
351 
352 Func_Done:
353     return 0;
354 }
355 
356 /*
357  * Process a main item.
358  */
hid_parser_main_Port3(struct hid_parser * parser,struct hid_item * item)359  int hid_parser_main_Port3(struct hid_parser *parser, struct hid_item *item)
360 {
361 	__u32 adata;
362 	int ret=0;
363 
364    // printf("  hid_parser_main   \n");
365 
366 	adata = item_udata_Port3(item);
367       // printf("TAG:%02bx\n",item->tag);
368 	switch (item->tag) {
369 		case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
370 #if 0
371                      if (adata==HID_COLLECTION_APPLICATION)
372                         {
373 				//printf("application\n");
374                             gOffsetBit=0;
375                             axis_idx=0;
376                             for (i=0 ; i < MAX_AXIS_NUM ; i ++)
377                             {
378                                 axis[i].size=0;
379                                 axis[i].val=0;
380                             }
381                         }
382 #endif
383 			ret = open_collection_Port3(parser, adata & 3);
384 			break;
385 		case HID_MAIN_ITEM_TAG_END_COLLECTION:
386 			ret = close_collection_Port3(parser);
387 			break;
388 		case HID_MAIN_ITEM_TAG_INPUT:
389                         ret = hid_chk_variable_Port3(parser, HID_INPUT_REPORT);
390 			//ret = hid_add_field(parser, HID_INPUT_REPORT, data);
391 			break;
392 		case HID_MAIN_ITEM_TAG_OUTPUT:
393                         ret = hid_chk_variable_Port3(parser, HID_OUTPUT_REPORT);
394 			//ret = hid_add_field(parser, HID_OUTPUT_REPORT, data);
395 			break;
396 		case HID_MAIN_ITEM_TAG_FEATURE:
397                         ret = hid_chk_variable_Port3(parser, HID_FEATURE_REPORT);
398 		//	ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
399 			break;
400 		default:
401 			//printf("unknown main item tag 0x%02bx", item->tag);
402 			ret = 0;
403 	}
404 
405 	memset(&parser->local, 0, sizeof(parser->local));	/* Reset the local parser environment */
406 
407 	return ret;
408 }
409 
410 
411 /*
412  * Process a global item.
413  */
414 
hid_parser_global_Port3(struct hid_parser * parser,struct hid_item * item)415  int hid_parser_global_Port3(struct hid_parser *parser, struct hid_item *item)
416 {
417    // printf("  hid_parser_global   \n");
418 	switch (item->tag) {
419 
420 		case HID_GLOBAL_ITEM_TAG_PUSH:
421 
422 			//if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
423 			//	printf("global enviroment stack overflow");
424 				//return -1;
425 			//}
426 
427 			//memcpy(parser->global_stack + parser->global_stack_ptr++,
428 				//&parser->global, sizeof(struct hid_global));
429 			return 0;
430 
431 		case HID_GLOBAL_ITEM_TAG_POP:
432 
433 			//if (!parser->global_stack_ptr) {
434 			//	printf("global enviroment stack underflow");
435 			//	return -1;
436 			//}
437 
438 			//memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr,
439 				//sizeof(struct hid_global));
440 			return 0;
441 
442 		case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
443 			parser->global.usage_page = item_udata_Port3(item);
444 
445                     USB_HID_DBG(printf("Find a usage page: %lX\n", parser->global.usage_page));
446 #if 0
447                      if (parser->global.usage_page==USEAGE_PAGE_BUTTON)
448                         {
449                             buttons.startbit=gOffsetBit;
450                             printf("buttons start:%x\n",buttons.startbit);
451                             buttons.count=parser->global.report_count;
452                             printf("buttons count:%02bx\n",buttons.count);
453 
454                             gOffsetBit+=buttons.count;
455                         }
456 #endif
457 			return 0;
458 
459 		case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:
460 			parser->global.logical_minimum = item_sdata_Port3(item);
461 			return 0;
462 
463 		case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
464 			if (parser->global.logical_minimum < 0)
465 				parser->global.logical_maximum = item_sdata_Port3(item);
466 			else
467 				parser->global.logical_maximum = item_udata_Port3(item);
468 			return 0;
469 
470 		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
471 			parser->global.physical_minimum = item_sdata_Port3(item);
472 			return 0;
473 
474 		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
475 			if (parser->global.physical_minimum < 0)
476 				parser->global.physical_maximum = item_sdata_Port3(item);
477 			else
478 				parser->global.physical_maximum = item_udata_Port3(item);
479 			return 0;
480 
481 		case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
482 			parser->global.unit_exponent = item_udata_Port3(item);
483 			return 0;
484 
485 		case HID_GLOBAL_ITEM_TAG_UNIT:
486 			parser->global.unit = item_udata_Port3(item);
487 			return 0;
488 
489 		case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
490 			if ((parser->global.report_size = item_udata_Port3(item)) > 32) {
491 			//	printf("invalid report_size %d", parser->global.report_size);
492 				return -1;
493 			}
494 			return 0;
495 
496 		case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
497 			if ((parser->global.report_count = item_udata_Port3(item)) > HID_MAX_USAGES) {
498 				//printf("invalid report_count %d", parser->global.report_count);
499 				return -1;
500 			}
501 			return 0;
502 
503 		case HID_GLOBAL_ITEM_TAG_REPORT_ID:
504 			if ((parser->global.report_id = item_udata_Port3(item)) == 0) {
505 				//printf("report_id 0 is invalid");
506 				return -1;
507 			}
508 			return 0;
509 
510 		default:
511 			//printf("unknown global tag 0x%02bx", item->tag);
512 			return -1;
513 	}
514 }
515 
hid_parser_local_Port3(struct hid_parser * parser,struct hid_item * item)516  int hid_parser_local_Port3(struct hid_parser *parser, struct hid_item *item)
517 {
518 	__u32 adata;
519 
520       //printf("  hid_parser_local   \n");
521 
522 	if (item->size == 0) {
523 		//printf("item data expected for local item");
524 		return -1;
525 	}
526 
527 	adata = item_udata_Port3(item);
528       //printf("local tag:%02bx\n",item->tag);
529 	switch (item->tag) {
530 
531 		case HID_LOCAL_ITEM_TAG_DELIMITER:
532 
533 			if (adata) {
534 				/*
535 				 * We treat items before the first delimiter
536 				 * as global to all usage sets (branch 0).
537 				 * In the moment we process only these global
538 				 * items and the first delimiter set.
539 				 */
540 				if (parser->local.delimiter_depth != 0) {
541 					//printf("nested delimiters");
542 					return -1;
543 				}
544 				parser->local.delimiter_depth++;
545 				parser->local.delimiter_branch++;
546 			} else {
547 				if (parser->local.delimiter_depth < 1) {
548 					//printf("bogus close delimiter");
549 					return -1;
550 				}
551 				parser->local.delimiter_depth--;
552 			}
553 			return 0;
554 
555 		case HID_LOCAL_ITEM_TAG_USAGE:
556 
557 			if (parser->local.delimiter_branch > 1) {
558 				//printf("alternative usage ignored");
559 				return 0;
560 			}
561 
562 			//if (item->size <= 2)
563 				//adata = (parser->global.usage_page << 16) + adata;
564 			USB_HID_DBG(printf("Find a usage: idx: %X, val: %lX\n", parser->local.usage_index, adata));
565                     parser->local.usage[parser->local.usage_index++] = adata;
566                   //   printf("useage:%lx\n",adata);
567 #if 0
568                      if (adata==USEAGE_X)
569                         {
570                              axis[axis_idx].startbit=gOffsetBit;
571                              axis[axis_idx].size=parser->global.report_size;
572                              axis[axis_idx].type=TYPE_AXIS_X;
573                              gOffsetBit+=axis[axis_idx].size;
574                              printf("Usage(X):%x\n",axis[axis_idx].startbit);
575 
576                              axis_idx++;
577                         }
578                      else if (adata==USEAGE_Y)
579                         {
580                              axis[axis_idx].startbit=gOffsetBit;
581                              axis[axis_idx].size=parser->global.report_size;
582                              axis[axis_idx].type=TYPE_AXIS_Y;
583                              gOffsetBit+=axis[axis_idx].size;
584                              printf("Usage(Y):%x\n",axis[axis_idx].startbit);
585 
586                              axis_idx++;
587                         }
588                      else if (adata==USEAGE_UNDEFINED)
589                         {
590                             printf("undefine usage :%02bx\n",parser->global.report_size);
591                             gOffsetBit+=parser->global.report_size;
592                         }
593 #endif
594 			return 0;// hid_add_usage(parser, data);
595 
596 		case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
597 
598 			if (parser->local.delimiter_branch > 1) {
599 				//printf("alternative usage ignored");
600 				return -1;
601 			}
602 
603 			if (item->size <= 2)
604 				adata = (parser->global.usage_page << 16) + adata;
605 
606 			parser->local.usage_minimum = adata;
607                     //  printf("logical minimum:%02bx\n",adata);
608 			return 0;
609 
610 		case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
611 
612 			if (parser->local.delimiter_branch > 1) {
613 				//printf("alternative usage ignored");
614 				return -1;
615 			}
616 
617 			if (item->size <= 2)
618 				adata = (parser->global.usage_page << 16) + adata;
619                     //  printf("logical maximum:%02bx\n",adata);
620 
621 			//for (n = parser->local.usage_minimum; n <= data; n++)
622 				//if (hid_add_usage(parser, n)) {
623 				//	printf("hid_add_usage failed\n");
624 				//	return -1;
625 				//}
626 			return 0;
627 
628 		default:
629 
630 			//printf("unknown local item tag 0x%x", item->tag);
631 			return -1;
632 	}
633 	return 0;
634 }
635 
hid_parse_report_Port3(__u8 * start,unsigned size)636 void hid_parse_report_Port3(__u8 *start, unsigned size)
637 {
638 	__u8 *end;
639        int result = 0;
640       struct hid_item xdata gitem;
641      struct hid_parser xdata gparser;
642 
643 
644   // printf("@@@ >>> Enter hid-core.c file --> hid_parse_report function \n");
645 
646 	memset((void*)&gparser, 0, sizeof(struct hid_parser));
647 	//parser->device = device;
648 
649 	end = start + size;
650 	while ((start = fetch_item_Port3(start, end, &gitem)) != 0)
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_Port3(&gparser,&gitem);
662         else if (gitem.type==1)
663             result=hid_parser_global_Port3(&gparser,&gitem);
664         else if (gitem.type==2)
665             result=hid_parser_local_Port3(&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_Port3(__u8 * report)692 U16 Parse_Joystick_Report_Port3(__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_Port3[i].size)                //this AXIS exist
703                 {
704                         tmp=GetValue_Port3(report,axis_Port3[i].startbit,axis_Port3[i].size);
705                         if (axis_Port3[i].val!=tmp )
706                             {
707                                  USB_HID_DBG(printf(" axis idx %x, offset:%x ,val %02x  tmp:%02x\n", i,axis_Port3[i].startbit,axis_Port3[i].val,tmp));
708                                  axis_Port3[i].val=tmp;
709                                  result=(axis_Port3[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_Port3(report,buttons_Port3.startbit,buttons_Port3.count);
719            // printf("tmp2:%x\n",tmp2);
720             if (buttons_Port3.val!=tmp2)
721                 {
722                     USB_HID_DBG(printf("buttons:%x %x\n",buttons_Port3.val, tmp2));
723                     buttons_Port3.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_Port3(__u8 * buf,__u16 offset,__u8 size)731 __u32 GetValue_Port3(__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_PORT3[]        = {0x81,0x06,0x00,0x22,0x00,0x00,0x65,0x00};
752 
GetReportDescriptor_Port3(void)753 BOOLEAN GetReportDescriptor_Port3(void)
754 {
755     UINT8 bCMD[8];
756     UINT8 i;
757 
758    memcpy(bCMD,GET_REPORT_DESCRIPTOR_PORT3,8);
759    if ( flib_Host20_Issue_Control_Port3 (1,bCMD,0x65,pUsbData_Port3)>0)
760        return FALSE;
761 
762     gOffsetBit_Port3=0;
763     axis_idx_Port3=0;
764     for (i=0 ; i < MAX_AXIS_NUM ; i++)
765     {
766         axis_Port3[i].size=0;
767         axis_Port3[i].val=0;
768     }
769 
770     buttons_Port3.count = 0;
771     buttons_Port3.startbit = 0;
772     buttons_Port3.val = 0;
773 
774    hid_parse_report_Port3(pUsbData_Port3, 0x65);
775 
776    return TRUE;
777 
778 }
drvUSBHost_HID_Initial_Port3(void)779 U8 drvUSBHost_HID_Initial_Port3(void)
780 {
781     USB_HID_DBG(printf("HID device\n"));
782 
783     GetReportDescriptor_Port3();
784 
785     pUsbIntrData_Port3=(U8*) KSEG02KSEG1(UsbIntrData_Port3);
786     MY_HAL_DCACHE_FLUSH((U32)UsbIntrData_Port3, 16);
787     flib_Host20_Interrupt_Init_Port3(3);
788 
789     return 0;
790 }
MDrv_GET_JOYSTICK_STATUS_Port3(void)791 U16  MDrv_GET_JOYSTICK_STATUS_Port3(void)
792 {
793     __u16 tmp=0;
794 
795     //printf("x1");
796 
797     memset(pUsbIntrData_Port3, 0, 8);
798      if (flib_Host20_Issue_Interrupt_Port3((U32)pUsbIntrData_Port3,8)==HOST20_OK)
799          tmp=Parse_Joystick_Report_Port3(pUsbIntrData_Port3);
800 // printf("x3");
801 
802      return tmp;
803 }
804 
805 U8  ReportData_Port3[8];
MDrv_Get_HID_Report_Raw_Data_Port3(void)806 U8*  MDrv_Get_HID_Report_Raw_Data_Port3(void)
807 {
808     U8  i;
809 
810     memset(ReportData_Port3, 0, 8);
811     if (flib_Host20_Issue_Interrupt_Port3((U32)pUsbIntrData_Port3,8)==HOST20_OK)
812     {
813         for (i=0 ; i <8 ; i++)
814         {
815             ReportData_Port3[i]=pUsbIntrData_Port3[i];
816             // printf("%02bx ",ReportData[i]);
817         }
818     }
819 
820     return ReportData_Port3;
821 }
822 #endif //#if defined(MSOS_TYPE_NOS)
823 
824 
825