Lines Matching +full:sw +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 1998-2005 Vojtech Pavlik
96 } sw_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-…
98 struct sw { struct
125 i = -id; /* Don't care about data, only want ID */ in sw_read_packet()
140 bitout--; in sw_read_packet()
150 timeout--; in sw_read_packet()
151 bitout--; /* Decrement timers */ in sw_read_packet()
152 sched--; in sw_read_packet()
157 if ((~u & v & 0x10) && (bitout > 0)) { /* Rising edge on clock - data bit */ in sw_read_packet()
170 if (pending && sched < 0 && (i > -SW_END)) { /* Second trigger time */ in sw_read_packet()
178 local_irq_restore(flags); /* Done - relax */ in sw_read_packet()
199 #define GB(pos,num) sw_get_bits(buf, pos, num, sw->bits)
208 while (num--) { in sw_get_bits()
221 * into digital mode.
236 while ((gameport_read(gameport) & 1) && t) t--; /* Wait for axis to fall back to 0 */ in sw_init_digital()
270 return -1; in sw_check()
285 static int sw_parse(unsigned char *buf, struct sw *sw) in sw_parse() argument
290 switch (sw->type) { in sw_parse()
295 return -1; in sw_parse()
297 dev = sw->dev[0]; in sw_parse()
319 for (i = 0; i < sw->number; i ++) { in sw_parse()
322 return -1; in sw_parse()
324 input_report_abs(sw->dev[i], ABS_X, GB(i*15+3,1) - GB(i*15+2,1)); in sw_parse()
325 input_report_abs(sw->dev[i], ABS_Y, GB(i*15+0,1) - GB(i*15+1,1)); in sw_parse()
328 input_report_key(sw->dev[i], sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1)); in sw_parse()
330 input_sync(sw->dev[i]); in sw_parse()
339 return -1; in sw_parse()
341 dev = sw->dev[0]; in sw_parse()
360 return -1; in sw_parse()
362 dev = sw->dev[0]; in sw_parse()
385 return -1; in sw_parse()
387 dev = sw->dev[0]; in sw_parse()
400 return -1; in sw_parse()
409 static int sw_read(struct sw *sw) in sw_read() argument
414 i = sw_read_packet(sw->gameport, buf, sw->length, 0); in sw_read()
416 if (sw->type == SW_ID_3DP && sw->length == 66 && i != 66) { /* Broken packet, try to fix */ in sw_read()
418 if (i == 64 && !sw_check(sw_get_bits(buf,0,64,1))) { /* Last init failed, 1 bit mode */ in sw_read()
419 printk(KERN_WARNING "sidewinder.c: Joystick in wrong mode on %s" in sw_read()
420 " - going to reinitialize.\n", sw->gameport->phys); in sw_read()
421 sw->fail = SW_FAIL; /* Reinitialize */ in sw_read()
425 if (i < 66 && GB(0,64) == GB(i*3-66,64)) /* 1 == 3 */ in sw_read()
431 if (i < 66 && GB(i*3-132,64) == GB(i*3-66,64)) { /* 2 == 3 */ in sw_read()
432 memmove(buf, buf + i - 22, 22); /* Move data */ in sw_read()
437 if (i == sw->length && !sw_parse(buf, sw)) { /* Parse data */ in sw_read()
439 sw->fail = 0; in sw_read()
440 sw->ok++; in sw_read()
442 if (sw->type == SW_ID_3DP && sw->length == 66 /* Many packets OK */ in sw_read()
443 && sw->ok > SW_OK) { in sw_read()
446 " - enabling optimization again.\n", sw->gameport->phys); in sw_read()
447 sw->length = 22; in sw_read()
453 sw->ok = 0; in sw_read()
454 sw->fail++; in sw_read()
456 if (sw->type == SW_ID_3DP && sw->length == 22 && sw->fail > SW_BAD) { /* Consecutive bad packets */ in sw_read()
459 " - disabling optimization.\n", sw->gameport->phys); in sw_read()
460 sw->length = 66; in sw_read()
463 if (sw->fail < SW_FAIL) in sw_read()
464 return -1; /* Not enough, don't reinitialize yet */ in sw_read()
467 " - reinitializing joystick.\n", sw->gameport->phys); in sw_read()
469 if (!i && sw->type == SW_ID_3DP) { /* 3D Pro can be in analog mode */ in sw_read()
471 sw_init_digital(sw->gameport); in sw_read()
475 i = sw_read_packet(sw->gameport, buf, SW_LENGTH, 0); /* Read normal data packet */ in sw_read()
477 sw_read_packet(sw->gameport, buf, SW_LENGTH, i); /* Read ID packet, this initializes the stick */ in sw_read()
479 sw->fail = SW_FAIL; in sw_read()
481 return -1; in sw_read()
486 struct sw *sw = gameport_get_drvdata(gameport); in sw_poll() local
488 sw->reads++; in sw_poll()
489 if (sw_read(sw)) in sw_poll()
490 sw->bads++; in sw_poll()
495 struct sw *sw = input_get_drvdata(dev); in sw_open() local
497 gameport_start_polling(sw->gameport); in sw_open()
503 struct sw *sw = input_get_drvdata(dev); in sw_close() local
505 gameport_stop_polling(sw->gameport); in sw_close()
517 for (i = (((length + 3) >> 2) - 1); i >= 0; i--) in sw_print_packet()
524 * Unfortunately I don't know how to do this for the other SW types.
541 (int) ((sw_get_bits(buf, 8, 6, 1) << 6) | /* Two 6-bit values */ in sw_3dp_id()
549 * sw_guess_mode() checks the upper two button bits for toggling -
550 * indication of that the joystick is in 3-bit mode. This is documented
561 xor |= (buf[i - 1] ^ buf[i]) & 6; in sw_guess_mode()
572 struct sw *sw; in sw_connect() local
583 sw = kzalloc(sizeof(struct sw), GFP_KERNEL); in sw_connect()
586 if (!sw || !buf || !idbuf) { in sw_connect()
587 err = -ENOMEM; in sw_connect()
591 sw->gameport = gameport; in sw_connect()
593 gameport_set_drvdata(gameport, sw); in sw_connect()
600 gameport->phys, gameport->io, gameport->speed); in sw_connect()
604 dbg("Init 1: Mode %d. Length %d.", m , i); in sw_connect()
606 if (!i) { /* No data. 3d Pro analog mode? */ in sw_connect()
612 if (!i) { /* No data -> FAIL */ in sw_connect()
613 err = -ENODEV; in sw_connect()
619 m |= sw_guess_mode(idbuf, j); /* ID packet should carry mode info [3DP] */ in sw_connect()
620 dbg("Init 2: Mode %d. ID Length %d.", m, j); in sw_connect()
622 if (j <= 0) { /* Read ID failed. Happens in 1-bit mode on PP */ in sw_connect()
626 dbg("Init 2b: Mode %d. Length %d.", m, i); in sw_connect()
628 err = -ENODEV; in sw_connect()
636 sw->type = -1; in sw_connect()
641 k--; in sw_connect()
644 dbg("Init 3: Mode %d. Length %d. Last %d. Tries %d.", m, i, l, k); in sw_connect()
650 sw->number = 1; in sw_connect()
651 sw->gameport = gameport; in sw_connect()
652 sw->length = i; in sw_connect()
653 sw->bits = m; in sw_connect()
659 sw->number++; in sw_connect()
662 if (j <= 40) { /* ID length less or eq 40 -> FSP */ in sw_connect()
664 sw->type = SW_ID_FSP; in sw_connect()
667 sw->number++; in sw_connect()
670 sw->number++; in sw_connect()
673 sw->type = SW_ID_GP; in sw_connect()
677 sw->type = SW_ID_FFW; in sw_connect()
680 if (j == 14) { /* ID length 14*3 -> FFP */ in sw_connect()
681 sw->type = SW_ID_FFP; in sw_connect()
684 sw->type = SW_ID_PP; in sw_connect()
687 sw->bits = 3; in sw_connect()
690 sw->length = 22; in sw_connect()
693 sw->type = SW_ID_3DP; in sw_connect()
700 } while (k && sw->type == -1); in sw_connect()
702 if (sw->type == -1) { in sw_connect()
704 "on %s, contact <vojtech@ucw.cz>\n", gameport->phys); in sw_connect()
707 err = -ENODEV; in sw_connect()
722 for (i = 0; i < sw->number; i++) { in sw_connect()
725 snprintf(sw->name, sizeof(sw->name), in sw_connect()
726 "Microsoft SideWinder %s", sw_name[sw->type]); in sw_connect()
727 snprintf(sw->phys[i], sizeof(sw->phys[i]), in sw_connect()
728 "%s/input%d", gameport->phys, i); in sw_connect()
730 sw->dev[i] = input_dev = input_allocate_device(); in sw_connect()
732 err = -ENOMEM; in sw_connect()
736 input_dev->name = sw->name; in sw_connect()
737 input_dev->phys = sw->phys[i]; in sw_connect()
738 input_dev->id.bustype = BUS_GAMEPORT; in sw_connect()
739 input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT; in sw_connect()
740 input_dev->id.product = sw->type; in sw_connect()
741 input_dev->id.version = 0x0100; in sw_connect()
742 input_dev->dev.parent = &gameport->dev; in sw_connect()
744 input_set_drvdata(input_dev, sw); in sw_connect()
746 input_dev->open = sw_open; in sw_connect()
747 input_dev->close = sw_close; in sw_connect()
749 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); in sw_connect()
751 for (j = 0; (bits = sw_bit[sw->type][j]); j++) { in sw_connect()
754 code = sw_abs[sw->type][j]; in sw_connect()
755 min = bits == 1 ? -1 : 0; in sw_connect()
756 max = (1 << bits) - 1; in sw_connect()
757 fuzz = (bits >> 1) >= 2 ? 1 << ((bits >> 1) - 2) : 0; in sw_connect()
759 0 : 1 << (bits - 5); in sw_connect()
765 for (j = 0; (code = sw_btn[sw->type][j]); j++) in sw_connect()
766 __set_bit(code, input_dev->keybit); in sw_connect()
768 dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k); in sw_connect()
770 err = input_register_device(sw->dev[i]); in sw_connect()
780 fail4: input_free_device(sw->dev[i]); in sw_connect()
781 fail3: while (--i >= 0) in sw_connect()
782 input_unregister_device(sw->dev[i]); in sw_connect()
785 kfree(sw); in sw_connect()
791 struct sw *sw = gameport_get_drvdata(gameport); in sw_disconnect() local
794 for (i = 0; i < sw->number; i++) in sw_disconnect()
795 input_unregister_device(sw->dev[i]); in sw_disconnect()
798 kfree(sw); in sw_disconnect()