OBJS+=irq.o
OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o
-OBJS+=ssd0303.o ssd0323.o ads7846.o
+OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o
OBJS+=scsi-disk.o cdrom.o
OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o
void ads7846_write(void *opaque, uint32_t value);
struct ads7846_state_s *ads7846_init(qemu_irq penirq);
+/* stellaris_input.c */
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
+
#endif
qemu_irq qemu_irq_invert(qemu_irq irq)
{
+ /* The default state for IRQs is low, so raise the output now. */
+ qemu_irq_raise(irq);
return qemu_allocate_irqs(qemu_notirq, irq, 1)[0];
}
#include "sysemu.h"
#include "boards.h"
+#define GPIO_A 0
+#define GPIO_B 1
+#define GPIO_C 2
+#define GPIO_D 3
+#define GPIO_E 4
+#define GPIO_F 5
+#define GPIO_G 6
+
+#define BP_OLED_I2C 0x01
+#define BP_OLED_SSI 0x02
+#define BP_GAMEPAD 0x04
+
typedef const struct {
const char *name;
uint32_t did0;
uint32_t dc2;
uint32_t dc3;
uint32_t dc4;
- enum {OLED_I2C, OLED_SSI} oled;
+ uint32_t peripherals;
} stellaris_board_info;
/* General purpose timer module. */
0x01071013,
0x3f0f01ff,
0x0000001f,
- OLED_I2C
+ BP_OLED_I2C
},
{ "LM3S6965EVB",
0x10010002,
0x030f5317,
0x0f0f87ff,
0x5000007f,
- OLED_SSI
+ BP_OLED_SSI | BP_GAMEPAD
}
};
if (board->dc2 & (1 << 12)) {
i2c = i2c_init_bus();
stellaris_i2c_init(0x40020000, pic[8], i2c);
- if (board->oled == OLED_I2C) {
+ if (board->peripherals & BP_OLED_I2C) {
ssd0303_init(ds, i2c, 0x3d);
}
}
}
}
if (board->dc2 & (1 << 4)) {
- if (board->oled == OLED_SSI) {
+ if (board->peripherals & BP_OLED_SSI) {
void * oled;
/* FIXME: Implement chip select for OLED/MMC. */
- oled = ssd0323_init(ds, &gpio_out[2][7]);
+ oled = ssd0323_init(ds, &gpio_out[GPIO_C][7]);
pl022_init(0x40008000, pic[7], ssd0323_xfer_ssi, oled);
} else {
pl022_init(0x40008000, pic[7], NULL, NULL);
}
}
+ if (board->peripherals & BP_GAMEPAD) {
+ qemu_irq gpad_irq[5];
+ static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
+
+ gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
+ gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
+ gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
+ gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
+ gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
+
+ stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
+ }
}
/* FIXME: Figure out how to generate these from stellaris_boards. */
--- /dev/null
+/*
+ * Gamepad style buttons connected to IRQ/GPIO lines
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ * Written by Paul Brook
+ *
+ * This code is licenced under the GPL.
+ */
+#include "hw.h"
+#include "devices.h"
+#include "console.h"
+
+typedef struct {
+ qemu_irq irq;
+ int keycode;
+ int pressed;
+} gamepad_button;
+
+typedef struct {
+ gamepad_button *buttons;
+ int num_buttons;
+ int extension;
+} gamepad_state;
+
+static void stellaris_gamepad_put_key(void * opaque, int keycode)
+{
+ gamepad_state *s = (gamepad_state *)opaque;
+ int i;
+ int down;
+
+ if (keycode == 0xe0 && !s->extension) {
+ s->extension = 0x80;
+ return;
+ }
+
+ down = (keycode & 0x80) == 0;
+ keycode = (keycode & 0x7f) | s->extension;
+
+ for (i = 0; i < s->num_buttons; i++) {
+ if (s->buttons[i].keycode == keycode
+ && s->buttons[i].pressed != down) {
+ s->buttons[i].pressed = down;
+ qemu_set_irq(s->buttons[i].irq, down);
+ }
+ }
+
+ s->extension = 0;
+}
+
+/* Returns an array 5 ouput slots. */
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
+{
+ gamepad_state *s;
+ int i;
+
+ s = (gamepad_state *)qemu_mallocz(sizeof (gamepad_state));
+ s->buttons = (gamepad_button *)qemu_mallocz(n * sizeof (gamepad_button));
+ for (i = 0; i < n; i++) {
+ s->buttons[i].irq = irq[i];
+ s->buttons[i].keycode = keycode[i];
+ }
+ s->num_buttons = n;
+ qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
+}
+
+