Commit cf0dbb21156f2fabdbe8b846b16dfc9825d8b23c
1 parent
f090c9d4
Luminary board input support.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3689 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
102 additions
and
7 deletions
Makefile
| ... | ... | @@ -54,7 +54,7 @@ OBJS+=block.o |
| 54 | 54 | |
| 55 | 55 | OBJS+=irq.o |
| 56 | 56 | OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o |
| 57 | -OBJS+=ssd0303.o ssd0323.o ads7846.o | |
| 57 | +OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o | |
| 58 | 58 | OBJS+=scsi-disk.o cdrom.o |
| 59 | 59 | OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o |
| 60 | 60 | ... | ... |
hw/devices.h
| ... | ... | @@ -16,4 +16,7 @@ uint32_t ads7846_read(void *opaque); |
| 16 | 16 | void ads7846_write(void *opaque, uint32_t value); |
| 17 | 17 | struct ads7846_state_s *ads7846_init(qemu_irq penirq); |
| 18 | 18 | |
| 19 | +/* stellaris_input.c */ | |
| 20 | +void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode); | |
| 21 | + | |
| 19 | 22 | #endif | ... | ... |
hw/irq.c
| ... | ... | @@ -65,5 +65,7 @@ static void qemu_notirq(void *opaque, int line, int level) |
| 65 | 65 | |
| 66 | 66 | qemu_irq qemu_irq_invert(qemu_irq irq) |
| 67 | 67 | { |
| 68 | + /* The default state for IRQs is low, so raise the output now. */ | |
| 69 | + qemu_irq_raise(irq); | |
| 68 | 70 | return qemu_allocate_irqs(qemu_notirq, irq, 1)[0]; |
| 69 | 71 | } | ... | ... |
hw/stellaris.c
| ... | ... | @@ -16,6 +16,18 @@ |
| 16 | 16 | #include "sysemu.h" |
| 17 | 17 | #include "boards.h" |
| 18 | 18 | |
| 19 | +#define GPIO_A 0 | |
| 20 | +#define GPIO_B 1 | |
| 21 | +#define GPIO_C 2 | |
| 22 | +#define GPIO_D 3 | |
| 23 | +#define GPIO_E 4 | |
| 24 | +#define GPIO_F 5 | |
| 25 | +#define GPIO_G 6 | |
| 26 | + | |
| 27 | +#define BP_OLED_I2C 0x01 | |
| 28 | +#define BP_OLED_SSI 0x02 | |
| 29 | +#define BP_GAMEPAD 0x04 | |
| 30 | + | |
| 19 | 31 | typedef const struct { |
| 20 | 32 | const char *name; |
| 21 | 33 | uint32_t did0; |
| ... | ... | @@ -25,7 +37,7 @@ typedef const struct { |
| 25 | 37 | uint32_t dc2; |
| 26 | 38 | uint32_t dc3; |
| 27 | 39 | uint32_t dc4; |
| 28 | - enum {OLED_I2C, OLED_SSI} oled; | |
| 40 | + uint32_t peripherals; | |
| 29 | 41 | } stellaris_board_info; |
| 30 | 42 | |
| 31 | 43 | /* General purpose timer module. */ |
| ... | ... | @@ -991,7 +1003,7 @@ static stellaris_board_info stellaris_boards[] = { |
| 991 | 1003 | 0x01071013, |
| 992 | 1004 | 0x3f0f01ff, |
| 993 | 1005 | 0x0000001f, |
| 994 | - OLED_I2C | |
| 1006 | + BP_OLED_I2C | |
| 995 | 1007 | }, |
| 996 | 1008 | { "LM3S6965EVB", |
| 997 | 1009 | 0x10010002, |
| ... | ... | @@ -1001,7 +1013,7 @@ static stellaris_board_info stellaris_boards[] = { |
| 1001 | 1013 | 0x030f5317, |
| 1002 | 1014 | 0x0f0f87ff, |
| 1003 | 1015 | 0x5000007f, |
| 1004 | - OLED_SSI | |
| 1016 | + BP_OLED_SSI | BP_GAMEPAD | |
| 1005 | 1017 | } |
| 1006 | 1018 | }; |
| 1007 | 1019 | |
| ... | ... | @@ -1052,7 +1064,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, |
| 1052 | 1064 | if (board->dc2 & (1 << 12)) { |
| 1053 | 1065 | i2c = i2c_init_bus(); |
| 1054 | 1066 | stellaris_i2c_init(0x40020000, pic[8], i2c); |
| 1055 | - if (board->oled == OLED_I2C) { | |
| 1067 | + if (board->peripherals & BP_OLED_I2C) { | |
| 1056 | 1068 | ssd0303_init(ds, i2c, 0x3d); |
| 1057 | 1069 | } |
| 1058 | 1070 | } |
| ... | ... | @@ -1064,15 +1076,27 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, |
| 1064 | 1076 | } |
| 1065 | 1077 | } |
| 1066 | 1078 | if (board->dc2 & (1 << 4)) { |
| 1067 | - if (board->oled == OLED_SSI) { | |
| 1079 | + if (board->peripherals & BP_OLED_SSI) { | |
| 1068 | 1080 | void * oled; |
| 1069 | 1081 | /* FIXME: Implement chip select for OLED/MMC. */ |
| 1070 | - oled = ssd0323_init(ds, &gpio_out[2][7]); | |
| 1082 | + oled = ssd0323_init(ds, &gpio_out[GPIO_C][7]); | |
| 1071 | 1083 | pl022_init(0x40008000, pic[7], ssd0323_xfer_ssi, oled); |
| 1072 | 1084 | } else { |
| 1073 | 1085 | pl022_init(0x40008000, pic[7], NULL, NULL); |
| 1074 | 1086 | } |
| 1075 | 1087 | } |
| 1088 | + if (board->peripherals & BP_GAMEPAD) { | |
| 1089 | + qemu_irq gpad_irq[5]; | |
| 1090 | + static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d }; | |
| 1091 | + | |
| 1092 | + gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */ | |
| 1093 | + gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */ | |
| 1094 | + gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */ | |
| 1095 | + gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */ | |
| 1096 | + gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */ | |
| 1097 | + | |
| 1098 | + stellaris_gamepad_init(5, gpad_irq, gpad_keycode); | |
| 1099 | + } | |
| 1076 | 1100 | } |
| 1077 | 1101 | |
| 1078 | 1102 | /* FIXME: Figure out how to generate these from stellaris_boards. */ | ... | ... |
hw/stellaris_input.c
0 → 100644
| 1 | +/* | |
| 2 | + * Gamepad style buttons connected to IRQ/GPIO lines | |
| 3 | + * | |
| 4 | + * Copyright (c) 2007 CodeSourcery. | |
| 5 | + * Written by Paul Brook | |
| 6 | + * | |
| 7 | + * This code is licenced under the GPL. | |
| 8 | + */ | |
| 9 | +#include "hw.h" | |
| 10 | +#include "devices.h" | |
| 11 | +#include "console.h" | |
| 12 | + | |
| 13 | +typedef struct { | |
| 14 | + qemu_irq irq; | |
| 15 | + int keycode; | |
| 16 | + int pressed; | |
| 17 | +} gamepad_button; | |
| 18 | + | |
| 19 | +typedef struct { | |
| 20 | + gamepad_button *buttons; | |
| 21 | + int num_buttons; | |
| 22 | + int extension; | |
| 23 | +} gamepad_state; | |
| 24 | + | |
| 25 | +static void stellaris_gamepad_put_key(void * opaque, int keycode) | |
| 26 | +{ | |
| 27 | + gamepad_state *s = (gamepad_state *)opaque; | |
| 28 | + int i; | |
| 29 | + int down; | |
| 30 | + | |
| 31 | + if (keycode == 0xe0 && !s->extension) { | |
| 32 | + s->extension = 0x80; | |
| 33 | + return; | |
| 34 | + } | |
| 35 | + | |
| 36 | + down = (keycode & 0x80) == 0; | |
| 37 | + keycode = (keycode & 0x7f) | s->extension; | |
| 38 | + | |
| 39 | + for (i = 0; i < s->num_buttons; i++) { | |
| 40 | + if (s->buttons[i].keycode == keycode | |
| 41 | + && s->buttons[i].pressed != down) { | |
| 42 | + s->buttons[i].pressed = down; | |
| 43 | + qemu_set_irq(s->buttons[i].irq, down); | |
| 44 | + } | |
| 45 | + } | |
| 46 | + | |
| 47 | + s->extension = 0; | |
| 48 | +} | |
| 49 | + | |
| 50 | +/* Returns an array 5 ouput slots. */ | |
| 51 | +void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode) | |
| 52 | +{ | |
| 53 | + gamepad_state *s; | |
| 54 | + int i; | |
| 55 | + | |
| 56 | + s = (gamepad_state *)qemu_mallocz(sizeof (gamepad_state)); | |
| 57 | + s->buttons = (gamepad_button *)qemu_mallocz(n * sizeof (gamepad_button)); | |
| 58 | + for (i = 0; i < n; i++) { | |
| 59 | + s->buttons[i].irq = irq[i]; | |
| 60 | + s->buttons[i].keycode = keycode[i]; | |
| 61 | + } | |
| 62 | + s->num_buttons = n; | |
| 63 | + qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s); | |
| 64 | +} | |
| 65 | + | |
| 66 | + | ... | ... |