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