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 | + | ... | ... |