neGT-USBを使わずにRPiにダイレクトにネジコンをつなぐ(Part4)
でgamecon_gpio_rpi.cの変更点を書いたのですが、GPIOの番号を可変出来るように修正したのでこれも載せておきます。
GC_PSX_COMMAND_PIN,GC_PSX_SELECT_PINで変更出来ますが、1X番台ではないと動作しませんでした。
--- gamecon_gpio_rpi_1.2_org.c 2015-12-28 07:27:26.000000000 +0900
+++ gamecon_gpio_rpi_1.2_new.c 2017-01-23 23:06:57.732432783 +0900
@@ -46,11 +46,11 @@
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
+static volatile unsigned *gpio;
+
#define GPIO_SET *(gpio+7)
#define GPIO_CLR *(gpio+10)
-static volatile unsigned *gpio;
-
struct gc_config {
int args[GC_MAX_DEVICES];
unsigned int nargs;
@@ -619,8 +619,7 @@
*
*/
-#define GC_PSX_DELAY 3 /* clock phase length in us. Valid clkfreq is 100kHz...500kHz. 2*udelay(3) results to ~250kHz on RPi1. */
-#define GC_PSX_DELAY2 25 /* delay between bytes. */
+#define GC_PSX_DELAY 10 /* 25 usec */
#define GC_PSX_LENGTH 8 /* talk to the controller in bits */
#define GC_PSX_BYTES 6 /* the maximum number of bytes to read off the controller */
@@ -630,13 +629,22 @@
#define GC_PSX_ANALOG 5 /* Analog in Analog mode / Rumble in Green mode */
#define GC_PSX_RUMBLE 7 /* Rumble in Red mode */
+#define GC_PSX_COMMAND_PIN 16 /* Pin 16 */
+#define GC_PSX_SELECT_PIN 17 /* Pin 17 */
+
+#define GC_GPIO(g) (((g)%10)*3)
+
#define GC_PSX_CLOCK (1<<18) /* Pin 18 */
-#define GC_PSX_COMMAND (1<<14) /* Pin 14 */
-#define GC_PSX_SELECT (1<<15) /* Pin 15 */
+#define GC_PSX_COMMAND (1<<GC_PSX_COMMAND_PIN)
+#define GC_PSX_SELECT (1<<GC_PSX_SELECT_PIN)
#define GC_PSX_ID(x) ((x) >> 4) /* High nibble is device type */
#define GC_PSX_LEN(x) (((x) & 0xf) << 1) /* Low nibble is length in bytes/2 */
+static int gc_psx_delay = GC_PSX_DELAY;
+module_param_named(psx_delay, gc_psx_delay, uint, 0);
+MODULE_PARM_DESC(psx_delay, "Delay when accessing Sony PSX controller (usecs)");
+
static const short gc_psx_abs[] = {
ABS_HAT0X, ABS_HAT0Y, ABS_RX, ABS_RY, ABS_X, ABS_Y
};
@@ -659,15 +667,14 @@
for (i = 0; i < GC_PSX_LENGTH; i++, b >>= 1) {
- GPIO_CLR = GC_PSX_CLOCK;
-
if (b & 1)
GPIO_SET = GC_PSX_COMMAND;
else
GPIO_CLR = GC_PSX_COMMAND;
-
- udelay(GC_PSX_DELAY);
- GPIO_SET = GC_PSX_CLOCK;
+
+ GPIO_CLR = GC_PSX_CLOCK;
+
+ udelay(gc_psx_delay);
read = *(gpio+13);
@@ -678,10 +685,10 @@
data[j] |= (read & gc_status_bit[j]) ? (1 << i) : 0;
}
- udelay(GC_PSX_DELAY);
+ GPIO_SET = GC_PSX_CLOCK;
+
+ udelay(gc_psx_delay);
}
-
- udelay(GC_PSX_DELAY2);
}
/*
@@ -697,14 +704,14 @@
unsigned long flags;
unsigned char data2[GC_MAX_DEVICES];
- local_irq_save(flags);
-
/* Select pad */
GPIO_SET = GC_PSX_CLOCK | GC_PSX_SELECT;
-
+ udelay(gc_psx_delay);
/* Deselect, begin command */
GPIO_CLR = GC_PSX_SELECT;
- udelay(GC_PSX_DELAY2);
+ udelay(gc_psx_delay);
+
+ local_irq_save(flags);
gc_psx_command(gc, 0x01, data2); /* Access pad */
gc_psx_command(gc, 0x42, id); /* Get device ids */
@@ -1146,9 +1153,16 @@
if (gc->pad_count[GC_PSX] ||
gc->pad_count[GC_DDR]) {
- /* set clk, cmd & sel pins to OUTPUT */
+ /* set clk, cmd & sel pins to OUTPUT
+ 12 = GPIO14(CMD)
+ 15 = GPIO15(SEL)
+ 24 = GPIO18(CLK)
+
*(gpio+1) &= ~((7<<12) | (7<<15) | (7<<24));
*(gpio+1) |= ((1<<12) | (1<<15) | (1<<24));
+ */
+ *(gpio+1) &= ~((7<<GC_GPIO(GC_PSX_COMMAND_PIN)) | (7<<GC_GPIO(GC_PSX_SELECT_PIN)) | (7<<24));
+ *(gpio+1) |= ((1<<GC_GPIO(GC_PSX_COMMAND_PIN)) | (1<<GC_GPIO(GC_PSX_SELECT_PIN)) | (1<<24));
}
return gc;
@@ -1190,6 +1204,9 @@
if (gc_cfg.nargs < 1) {
pr_err("at least one device must be specified\n");
return -EINVAL;
+ } else if ((gc_psx_delay < 1) || (gc_psx_delay > 50)) {
+ pr_err("Invalid psx_delay (1-50 allowed)\n");
+ return -EINVAL;
} else {
gc_base = gc_probe(gc_cfg.args, gc_cfg.nargs);
if (IS_ERR(gc_base))