db9.c (Re: [PATCH] gamecon (added support for Sega Saturn controller), kernel 2.4.20)

db9.c (Re: [PATCH] gamecon (added support for Sega Saturn controller), kernel 2.4.20)

Post by <yoko.. » Wed, 11 Jun 2003 15:20:11



Hello,

This is db9.c patch to support Saturn DPP.
I merged original interface section into DPP section to support
analog controllers. I gave priority to documentation of
joystick-parport.txt.

Set 11 or 12 in 'type' to use DPP (11 for a connector, 12 for two
connectors).

Tested with:
* DPP interface (one connector) and joystick-parport.txt interface.
* Digital controller, saturn keyboard (as joypad), racing controller,
  mission stick, multi controller, shuttle mouse, multi terminal 6,
  and sankyo ff.

NOT tested with:
* DPP interface (two connectors).
* Virtua Gun, mission stick x2, and other controllers.

Thank you for your reading,
  yokota

--- db9.c.orig  2001-09-13 07:34:06.000000000 +0900
+++ db9.c       2003-04-10 23:03:49.000000000 +0900
@@ -55,7 +55,9 @@
 #define DB9_MULTI_0802         0x08
 #define DB9_MULTI_0802_2       0x09
 #define DB9_CD32_PAD           0x0A
-#define DB9_MAX_PAD            0x0B
+#define DB9_SATURN_DPP         0x0B
+#define DB9_SATURN_DPP_2       0x0C
+#define DB9_MAX_PAD            0x0D

 #define DB9_UP                 0x01
 #define DB9_DOWN               0x02
@@ -69,10 +71,7 @@
 #define DB9_NORMAL             0x0a
 #define DB9_NOSELECT           0x08

-#define DB9_SATURN0            0x00
-#define DB9_SATURN1            0x02
-#define DB9_SATURN2            0x04
-#define DB9_SATURN3            0x06
+#define DB9_MAX_DEVICES 2

 #define DB9_GENESIS6_DELAY     14
 #define DB9_REFRESH_TIME       HZ/100
@@ -82,7 +81,7 @@
 static int db9_3[] __initdata = { -1, 0 };

 struct db9 {
-       struct input_dev dev[2];
+       struct input_dev dev[DB9_MAX_DEVICES];
        struct timer_list timer;
        struct pardevice *pd;  
        int mode;
@@ -95,12 +94,247 @@
 static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
 static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };

-static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 8, 1, 1, 7 };
+static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 9, 1, 1, 7, 9, 9 };
 static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn,
-                                       db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn };
+                                       db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn,
+                                       db9_cd32_btn, db9_cd32_btn };
 static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
                                      NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick",
-                                    "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad" };
+                                    "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad", "Saturn dpp", "Saturn dpp dual" };
+
+static const int db9_max_pads[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 6, 1, 2, 1, 6, 12 };
+static const int db9_num_axis[DB9_MAX_PAD] = { 0, 2, 2, 2, 0, 2, 2, 7, 2, 2, 2 ,7, 7 };
+static const short db9_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_RZ, ABS_Z, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
+static const int db9_bidirectional[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0 };
+static const int db9_reverse[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0 };
+
+/*
+ * Saturn controllers
+ */
+#define DB9_SATURN_DELAY 300
+static const int db9_saturn_byte[] = { 1, 1, 1, 2, 2, 2, 2, 2, 1 };
+static const unsigned char db9_saturn_mask[] = { 0x04, 0x01, 0x02, 0x40, 0x20, 0x10, 0x08, 0x80, 0x08 };
+
+/*
+ * db9_saturn_write_sub() writes 2 bit data.
+ */
+static void db9_saturn_write_sub(struct parport *port, int type, unsigned char data, int powered, int pwr_sub)
+{
+       unsigned char c;
+
+       switch (type) {
+       case 1: /* DPP1 */
+               c = 0x80 | 0x30 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | data;
+               parport_write_data(port, c);
+               break;
+       case 2: /* DPP2 */
+               c = 0x40 | data << 4 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | 0x03;
+               parport_write_data(port, c);
+               break;
+       case 0: /* DB9 */
+               c = ((((data & 2) ? 2 : 0) | ((data & 1) ? 4 : 0)) ^ 0x02) | !powered;
+               parport_write_control(port, c);
+               break;
+       }
+}
+
+/*
+ * gc_saturn_read_sub() reads 4 bit data.
+ */
+static unsigned char db9_saturn_read_sub(struct parport *port, int type)
+{
+       unsigned char data;
+
+       if (type) {
+               /* DPP */
+               data = parport_read_status(port) ^ 0x80;
+               return (data & 0x80 ? 1 : 0) | (data & 0x40 ? 2 : 0)
+                    | (data & 0x20 ? 4 : 0) | (data & 0x10 ? 8 : 0);
+       } else {
+               /* DB9 */
+               data = parport_read_data(port) & 0x0f;
+               return (data & 0x8 ? 1 : 0) | (data & 0x4 ? 2 : 0)
+                    | (data & 0x2 ? 4 : 0) | (data & 0x1 ? 8 : 0);
+       }
+}
+
+/*
+ * db9_saturn_read_analog() sends clock and reads 8 bit data.
+ */
+static unsigned char db9_saturn_read_analog(struct parport *port, int type, int powered)
+{
+       unsigned char data;
+
+       db9_saturn_write_sub(port, type, 0, powered, 0);
+       udelay(DB9_SATURN_DELAY);
+       data = db9_saturn_read_sub(port, type) << 4;
+       db9_saturn_write_sub(port, type, 2, powered, 0);
+       udelay(DB9_SATURN_DELAY);
+       data |= db9_saturn_read_sub(port, type);
+       return data;
+}
+
+/*
+ * db9_saturn_read_packet() reads whole saturn packet at connector
+ * and returns device identifier code.
+ */
+static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char *data, int type, int powered)
+{
+       int i, j;
+       unsigned char tmp;
+
+       db9_saturn_write_sub(port, type, 3, powered, 0);
+       data[0] = db9_saturn_read_sub(port, type);
+       switch (data[0] & 0x0f) {
+       case 0xf:
+               /* 1111  no pad */
+               return data[0] = 0xff;
+       case 0x4: case 0x4 | 0x8:
+               /* ?100 : digital controller */
+               db9_saturn_write_sub(port, type, 0, powered, 1);
+               data[2] = db9_saturn_read_sub(port, type) << 4;
+               db9_saturn_write_sub(port, type, 2, powered, 1);
+               data[1] = db9_saturn_read_sub(port, type) << 4;
+               db9_saturn_write_sub(port, type, 1, powered, 1);
+               data[1] |= db9_saturn_read_sub(port, type);
+               db9_saturn_write_sub(port, type, 3, powered, 1);
+               /* data[2] |= db9_saturn_read_sub(port, type); */
+               data[2] |= data[0];
+               return data[0] = 0x02;
+       case 0x1:
+               /* 0001 : analog controller or multitap */
+               db9_saturn_write_sub(port, type, 2, powered, 0);
+               udelay(DB9_SATURN_DELAY);
+               data[0] = db9_saturn_read_analog(port, type, powered);
+               if (data[0] != 0x41) {
+                       /* read analog controller */
+                       for (i = 0; i < (data[0] & 0x0f); i++)
+                               data[i + 1] = db9_saturn_read_analog(port, type, powered);
+                       db9_saturn_write_sub(port, type, 3, powered, 0);
+                       return data[0];
+               } else {
+                       /* read multitap */
+                       if (db9_saturn_read_analog(port, type, powered) != 0x60)
+                               return data[0] = 0xff;
+                       for (i = 0; i < 60; i += 10) {
+                               data[i] = db9_saturn_read_analog(port, type, powered);
+                               if (data[i] != 0xff)
+                                       /* read each pad */
+                                       for (j = 0; j < (data[i] & 0x0f); j++)
+                                               data[i + j + 1] = db9_saturn_read_analog(port, type, powered);
+                       }
+                       db9_saturn_write_sub(port, type, 3, powered, 0);
+                       return 0x41;
+               }
+       case 0x0:
+               /* 0000 : mouse */
+               db9_saturn_write_sub(port, type, 2, powered, 0);
+               udelay(DB9_SATURN_DELAY);
+               tmp = db9_saturn_read_analog(port, type, powered);
+               if (tmp == 0xff) {
+                       for (i = 0; i < 3; i++)
+                               data[i + 1] = db9_saturn_read_analog(port, type, powered);
+                       db9_saturn_write_sub(port, type, 3, powered, 0);
+                       return data[0] = 0xe3;
+               }
+       default:
+               return data[0];
+       }
+}
+
+/*
+ * db9_saturn_report() analyzes packet and reports.
+ */
+static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *dev, int n, int max_pads)
+{
+       int tmp, i, j;
+
+       tmp = (id == 0x41) ? 60 : 10;
+       for (j = 0; (j < tmp) && (n < max_pads); j += 10, n++) {
+               switch (data[j]) {
+               case 0x16: /* multi controller (analog 4 axis) */
+                       input_report_abs(dev + n, db9_abs[5], data[j + 6]);
+               case 0x15: /* mission stick (analog 3 axis) */
+                       input_report_abs(dev + n, db9_abs[3], data[j + 4]);
+                       input_report_abs(dev + n, db9_abs[4], data[j + 5]);
+               case 0x13: /* racing controller (analog 1 axis) */
+                       input_report_abs(dev + n, db9_abs[2], data[j + 3]);
+               case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */
+               case 0x02: /* digital pad (digital 2 axis + buttons) */
+                       input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
+                       input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
+                       for (i = 0; i < 9; i++)
+                               input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
+                       break;
+               case 0x19: /* mission stick x2 (analog 6 axis + buttons) */
+                       input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
+                       input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
+                       for (i = 0; i < 9; i++)
+                               input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
+                       input_report_abs(dev + n, db9_abs[2], data[j + 3]);
+                       input_report_abs(dev + n, db9_abs[3], data[j + 4]);
+                       input_report_abs(dev + n, db9_abs[4], data[j + 5]);
+                       /*
+                       input_report_abs(dev + n, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1));
+                       input_report_abs(dev + n, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1));
+                       */
+                       input_report_abs(dev + n, db9_abs[6], data[j + 7]);
+                       input_report_abs(dev + n, db9_abs[7], data[j + 8]);
+                       input_report_abs(dev + n, db9_abs[5], data[j + 9]);
+                       break;
+               case 0xd3: /* sankyo ff (analog 1 axis + stop btn) */
+                       input_report_key(dev + n, BTN_A, data[j + 3] & 0x80);
+                       input_report_abs(dev + n, db9_abs[2], data[j + 3] & 0x7f);
+                       break;
+               case 0xe3: /* shuttle mouse (analog 2 axis + buttons. signed value) */
+                       input_report_key(dev + n, BTN_START, data[j + 1] & 0x08);
+                       input_report_key(dev + n, BTN_A, data[j + 1] & 0x04);
+                       input_report_key(dev + n, BTN_C, data[j + 1] & 0x02);
+                       input_report_key(dev + n, BTN_B, data[j + 1] & 0x01);
+                       input_report_abs(dev + n, db9_abs[2], data[j + 2] ^ 0x80);
+                       input_report_abs(dev + n, db9_abs[3], (0xff-(data[j + 3] ^ 0x80))+1); /* */
+                       break;
+               case 0xff:
+               default: /* no pad */
+                       input_report_abs(dev +
...

read more »

 
 
 

db9.c (Re: [PATCH] gamecon (added support for Sega Saturn controller), kernel 2.4.20)

Post by Vojtech Pavli » Sun, 22 Jun 2003 18:10:10


On Tue, Jun 10, 2003 at 10:02:04PM +0900, yoko...@rmail.plala.or.jp wrote:
> Hello,

> This is db9.c patch to support Saturn DPP.
> I merged original interface section into DPP section to support
> analog controllers. I gave priority to documentation of
> joystick-parport.txt.

> Set 11 or 12 in 'type' to use DPP (11 for a connector, 12 for two
> connectors).

> Tested with:
> * DPP interface (one connector) and joystick-parport.txt interface.
> * Digital controller, saturn keyboard (as joypad), racing controller,
>   mission stick, multi controller, shuttle mouse, multi terminal 6,
>   and sankyo ff.

> NOT tested with:
> * DPP interface (two connectors).
> * Virtua Gun, mission stick x2, and other controllers.

> Thank you for your reading,
>   yokota

Thanks for the patch! I applied it to my kernel tree. How about a
patch to update for the joystick-parport.txt documentation file?

- Show quoted text -

> --- db9.c.orig     2001-09-13 07:34:06.000000000 +0900
> +++ db9.c  2003-04-10 23:03:49.000000000 +0900
> @@ -55,7 +55,9 @@
>  #define DB9_MULTI_0802            0x08
>  #define DB9_MULTI_0802_2  0x09
>  #define DB9_CD32_PAD              0x0A
> -#define DB9_MAX_PAD               0x0B
> +#define DB9_SATURN_DPP            0x0B
> +#define DB9_SATURN_DPP_2  0x0C
> +#define DB9_MAX_PAD               0x0D

>  #define DB9_UP                    0x01
>  #define DB9_DOWN          0x02
> @@ -69,10 +71,7 @@
>  #define DB9_NORMAL                0x0a
>  #define DB9_NOSELECT              0x08

> -#define DB9_SATURN0               0x00
> -#define DB9_SATURN1               0x02
> -#define DB9_SATURN2               0x04
> -#define DB9_SATURN3               0x06
> +#define DB9_MAX_DEVICES 2

>  #define DB9_GENESIS6_DELAY        14
>  #define DB9_REFRESH_TIME  HZ/100
> @@ -82,7 +81,7 @@
>  static int db9_3[] __initdata = { -1, 0 };

>  struct db9 {
> -  struct input_dev dev[2];
> +  struct input_dev dev[DB9_MAX_DEVICES];
>    struct timer_list timer;
>    struct pardevice *pd;  
>    int mode;
> @@ -95,12 +94,247 @@
>  static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
>  static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };

> -static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 8, 1, 1, 7 };
> +static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 9, 1, 1, 7, 9, 9 };
>  static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn,
> -                                  db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn };
> +                                  db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn,
> +                                  db9_cd32_btn, db9_cd32_btn };
>  static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
>                                  NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick",
> -                               "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad" };
> +                               "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad", "Saturn dpp", "Saturn dpp dual" };
> +
> +static const int db9_max_pads[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 6, 1, 2, 1, 6, 12 };
> +static const int db9_num_axis[DB9_MAX_PAD] = { 0, 2, 2, 2, 0, 2, 2, 7, 2, 2, 2 ,7, 7 };
> +static const short db9_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_RZ, ABS_Z, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
> +static const int db9_bidirectional[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0 };
> +static const int db9_reverse[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0 };
> +
> +/*
> + * Saturn controllers
> + */
> +#define DB9_SATURN_DELAY 300
> +static const int db9_saturn_byte[] = { 1, 1, 1, 2, 2, 2, 2, 2, 1 };
> +static const unsigned char db9_saturn_mask[] = { 0x04, 0x01, 0x02, 0x40, 0x20, 0x10, 0x08, 0x80, 0x08 };
> +
> +/*
> + * db9_saturn_write_sub() writes 2 bit data.
> + */
> +static void db9_saturn_write_sub(struct parport *port, int type, unsigned char data, int powered, int pwr_sub)
> +{
> +  unsigned char c;
> +
> +  switch (type) {
> +  case 1: /* DPP1 */
> +          c = 0x80 | 0x30 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | data;
> +          parport_write_data(port, c);
> +          break;
> +  case 2: /* DPP2 */
> +          c = 0x40 | data << 4 | (powered ? 0x08 : 0) | (pwr_sub ? 0x04 : 0) | 0x03;
> +          parport_write_data(port, c);
> +          break;
> +  case 0: /* DB9 */
> +          c = ((((data & 2) ? 2 : 0) | ((data & 1) ? 4 : 0)) ^ 0x02) | !powered;
> +          parport_write_control(port, c);
> +          break;
> +  }
> +}
> +
> +/*
> + * gc_saturn_read_sub() reads 4 bit data.
> + */
> +static unsigned char db9_saturn_read_sub(struct parport *port, int type)
> +{
> +  unsigned char data;
> +
> +  if (type) {
> +          /* DPP */
> +          data = parport_read_status(port) ^ 0x80;
> +          return (data & 0x80 ? 1 : 0) | (data & 0x40 ? 2 : 0)
> +               | (data & 0x20 ? 4 : 0) | (data & 0x10 ? 8 : 0);
> +  } else {
> +          /* DB9 */
> +          data = parport_read_data(port) & 0x0f;
> +          return (data & 0x8 ? 1 : 0) | (data & 0x4 ? 2 : 0)
> +               | (data & 0x2 ? 4 : 0) | (data & 0x1 ? 8 : 0);
> +  }
> +}
> +
> +/*
> + * db9_saturn_read_analog() sends clock and reads 8 bit data.
> + */
> +static unsigned char db9_saturn_read_analog(struct parport *port, int type, int powered)
> +{
> +  unsigned char data;
> +
> +  db9_saturn_write_sub(port, type, 0, powered, 0);
> +  udelay(DB9_SATURN_DELAY);
> +  data = db9_saturn_read_sub(port, type) << 4;
> +  db9_saturn_write_sub(port, type, 2, powered, 0);
> +  udelay(DB9_SATURN_DELAY);
> +  data |= db9_saturn_read_sub(port, type);
> +  return data;
> +}
> +
> +/*
> + * db9_saturn_read_packet() reads whole saturn packet at connector
> + * and returns device identifier code.
> + */
> +static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char *data, int type, int powered)
> +{
> +  int i, j;
> +  unsigned char tmp;
> +
> +  db9_saturn_write_sub(port, type, 3, powered, 0);
> +  data[0] = db9_saturn_read_sub(port, type);
> +  switch (data[0] & 0x0f) {
> +  case 0xf:
> +          /* 1111  no pad */
> +          return data[0] = 0xff;
> +  case 0x4: case 0x4 | 0x8:
> +          /* ?100 : digital controller */
> +          db9_saturn_write_sub(port, type, 0, powered, 1);
> +          data[2] = db9_saturn_read_sub(port, type) << 4;
> +          db9_saturn_write_sub(port, type, 2, powered, 1);
> +          data[1] = db9_saturn_read_sub(port, type) << 4;
> +          db9_saturn_write_sub(port, type, 1, powered, 1);
> +          data[1] |= db9_saturn_read_sub(port, type);
> +          db9_saturn_write_sub(port, type, 3, powered, 1);
> +          /* data[2] |= db9_saturn_read_sub(port, type); */
> +          data[2] |= data[0];
> +          return data[0] = 0x02;
> +  case 0x1:
> +          /* 0001 : analog controller or multitap */
> +          db9_saturn_write_sub(port, type, 2, powered, 0);
> +          udelay(DB9_SATURN_DELAY);
> +          data[0] = db9_saturn_read_analog(port, type, powered);
> +          if (data[0] != 0x41) {
> +                  /* read analog controller */
> +                  for (i = 0; i < (data[0] & 0x0f); i++)
> +                          data[i + 1] = db9_saturn_read_analog(port, type, powered);
> +                  db9_saturn_write_sub(port, type, 3, powered, 0);
> +                  return data[0];
> +          } else {
> +                  /* read multitap */
> +                  if (db9_saturn_read_analog(port, type, powered) != 0x60)
> +                          return data[0] = 0xff;
> +                  for (i = 0; i < 60; i += 10) {
> +                          data[i] = db9_saturn_read_analog(port, type, powered);
> +                          if (data[i] != 0xff)
> +                                  /* read each pad */
> +                                  for (j = 0; j < (data[i] & 0x0f); j++)
> +                                          data[i + j + 1] = db9_saturn_read_analog(port, type, powered);
> +                  }
> +                  db9_saturn_write_sub(port, type, 3, powered, 0);
> +                  return 0x41;
> +          }
> +  case 0x0:
> +          /* 0000 : mouse */
> +          db9_saturn_write_sub(port, type, 2, powered, 0);
> +          udelay(DB9_SATURN_DELAY);
> +          tmp = db9_saturn_read_analog(port, type, powered);
> +          if (tmp == 0xff) {
> +                  for (i = 0; i < 3; i++)
> +                          data[i + 1] = db9_saturn_read_analog(port, type, powered);
> +                  db9_saturn_write_sub(port, type, 3, powered, 0);
> +                  return data[0] = 0xe3;
> +          }
> +  default:
> +          return data[0];
> +  }
> +}
> +
> +/*
> + * db9_saturn_report() analyzes packet and reports.
> + */
> +static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *dev, int n, int max_pads)
> +{
> +  int tmp, i, j;
> +
> +  tmp = (id == 0x41) ? 60 : 10;
> +  for (j = 0; (j < tmp) && (n < max_pads); j += 10, n++) {
> +          switch (data[j]) {
> +          case 0x16: /* multi controller (analog 4 axis) */
> +                  input_report_abs(dev + n, db9_abs[5], data[j + 6]);
> +          case 0x15: /* mission stick (analog 3 axis) */
> +                  input_report_abs(dev + n, db9_abs[3], data[j + 4]);
> +                  input_report_abs(dev + n, db9_abs[4], data[j + 5]);
> +          case 0x13: /* racing controller (analog 1 axis) */
> +                  input_report_abs(dev + n, db9_abs[2], data[j + 3]);
> +          case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */
> +          case 0x02: /* digital pad (digital 2 axis + buttons) */
> +                  input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
> +                  input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
> +                  for (i = 0; i < 9; i++)
> +                          input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
> +                  break;
> +          case 0x19: /* mission stick x2 (analog 6 axis + buttons) */
> +                  input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
> +                  input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
> +                  for (i = 0; i < 9; i++)
> +                          input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
> +                  input_report_abs(dev + n, db9_abs[2], data[j + 3]);
> +                  input_report_abs(dev + n, db9_abs[3], data[j + 4]);
> +                  input_report_abs(dev + n, db9_abs[4], data[j + 5]);
> +                  /*
> +                  input_report_abs(dev + n, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1));
> +                  input_report_abs(dev + n, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1));
> +                  */
> +                  input_report_abs(dev + n, db9_abs[6], data[j + 7]);
> +                  input_report_abs(dev + n, db9_abs[7], data[j + 8]);
> +                  input_report_abs(dev + n, db9_abs[5], data[j + 9]);
> +                  break;
> +          case

...

read more »

 
 
 

db9.c (Re: [PATCH] gamecon (added support for Sega Saturn controller), kernel 2.4.20)

Post by <yoko.. » Tue, 24 Jun 2003 15:30:20


Hello,
Thank you very much for your reply and acceptance of my patch.


> Thanks for the patch! I applied it to my kernel tree. How about a
> patch to update for the joystick-parport.txt documentation file?

I updated jostick-parport.txt file. New saturn figure is equivalent
to previous documentation. It might require a review, especially in
language.

Thank you for your reading,
  yokota

--- joystick-parport.txt.orig   Thu Sep 13 07:34:06 2001

 2.4.3 Sega Saturn
 ~~~~~~~~~~~~~~~~~
-  Sega Saturn has eight buttons, and to transfer that, without hacks like
+  Sega Saturn has nine buttons, and to transfer that, without hacks like
 Genesis 6 pads use, it needs one more select pin. Anyway, it is still
 handled by the db9.c driver. Its pinout is very different from anything
 else.  Use this schematic:

-    +-----------> Select 1
-    | +---------> Power
-    | | +-------> Up
-    | | | +-----> Down
-    | | | | +---> Ground
-    | | | | |
-  _____________
-5 \ o o o o o / 1
-   \ o o o o /
-  9 `~~~~~~~' 6
-     | | | |
-     | | | +----> Select 2
-     | | +------> Right
-     | +--------> Left
-     +----------> Power
+  +-------------------> Ground (parallel port pin 18 - 25)
+  | +-----------------> Data 2 (pin 3)
+  | | +---------------> Data 3 (pin 2)
+  | | | +-------------> Power sub (pin 1)
+  | | | | +-----------> Select 1 (pin 14)
+  | | | | | +---------> Select 0 (pin 16)
+  | | | | | | +-------> Data 0 (pin 5)
+  | | | | | | | +-----> Data 1 (pin 4)
+  | | | | | | | | +---> Power (pin 1)
+  | | | | | | | | |
+ /= = = = = = = = =\
+| 1 2 3 4 5 6 7 8 9 |
++-------------------+

-  Select 1 is pin 14 on the parallel port, Select 2 is pin 16 on the
+  Select 1 is pin 14 on the parallel port, Select 0 is pin 16 on the
 parallel port.

 (pin 14) -----> Select 1
-(pin 16) -----> Select 2
+(pin 16) -----> Select 0

-  The other pins (Up, Down, Right, Left, Power, Ground) are the same as for
-Multi joysticks using db9.c
+  Data 2, 3, 0, 1 are connected to pins 3, 2, 5, 4 on the parallel port.
+
+(pin 3)  -----> Data 2
+(pin 2)  -----> Data 3
+(pin 5)  -----> Data 0
+(pin 4)  -----> Data 1
+
+  The other pins (Power, Ground) are the same as for Multi joysticks using
+db9.c
+
+  Power sub might require a resistor, when you use analog controller with
+external +5 volt power supply.
+
++5V supply ------+------------> Power (saturn 9)
+                 |  Resistor
+                 +--[10kOhm]--> Power sub (saturn 4)
+
+  On a side note, if you have already built a different adapter for use with
+DirectPadPro, this is also supported by the db9.c driver, as device type 11
+and 12. Use 11 for a connector, or 12 for two connectors. Two connectors are
+distinguished with its own Ground pins.
+
+  +-------------------> Ground (pin 8 or pin 9)
+  | +-----------------> Data 2 (pin 12)
+  | | +---------------> Data 3 (pin 13)
+  | | | +-------------> Power sub (pin 4)
+  | | | | +-----------> Select 1 (pin 3)
+  | | | | | +---------> Select 0 (pin 2)
+  | | | | | | +-------> Data 0 (pin 11)
+  | | | | | | | +-----> Data 1 (pin 10)
+  | | | | | | | | +---> Power (pin 5)
+  | | | | | | | | |
+ /= = = = = = = = =\
+| 1 2 3 4 5 6 7 8 9 |
++-------------------+

 3. The drivers

          3  | Genesis pad (3+1 buttons)
          5  | Genesis pad (5+1 buttons)
          6  | Genesis pad (6+2 buttons)
-         7  | Saturn pad (8 buttons)
+         7  | Saturn pad (9 buttons)
          8  | Multisystem 1-button joystick (v0.8.0.2 pin-out)
          9  | Two Multisystem 1-button joysticks (v0.8.0.2 pin-out)
         10  | Amiga CD32 pad
+        11  | Saturn pad (DirectPadPro pin-out)
+        12  | Two Saturn pads (DirectPadPro pin-out)

   Should you want to use more than one of these joysticks/pads at once, you
 can use db9_2 and db9_3 as additional command line parameters for two

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/