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,7 +54,7 @@ OBJS+=block.o | ||
54 | 54 | ||
55 | OBJS+=irq.o | 55 | OBJS+=irq.o |
56 | OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o | 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 | OBJS+=scsi-disk.o cdrom.o | 58 | OBJS+=scsi-disk.o cdrom.o |
59 | OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o | 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,4 +16,7 @@ uint32_t ads7846_read(void *opaque); | ||
16 | void ads7846_write(void *opaque, uint32_t value); | 16 | void ads7846_write(void *opaque, uint32_t value); |
17 | struct ads7846_state_s *ads7846_init(qemu_irq penirq); | 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 | #endif | 22 | #endif |
hw/irq.c
@@ -65,5 +65,7 @@ static void qemu_notirq(void *opaque, int line, int level) | @@ -65,5 +65,7 @@ static void qemu_notirq(void *opaque, int line, int level) | ||
65 | 65 | ||
66 | qemu_irq qemu_irq_invert(qemu_irq irq) | 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 | return qemu_allocate_irqs(qemu_notirq, irq, 1)[0]; | 70 | return qemu_allocate_irqs(qemu_notirq, irq, 1)[0]; |
69 | } | 71 | } |
hw/stellaris.c
@@ -16,6 +16,18 @@ | @@ -16,6 +16,18 @@ | ||
16 | #include "sysemu.h" | 16 | #include "sysemu.h" |
17 | #include "boards.h" | 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 | typedef const struct { | 31 | typedef const struct { |
20 | const char *name; | 32 | const char *name; |
21 | uint32_t did0; | 33 | uint32_t did0; |
@@ -25,7 +37,7 @@ typedef const struct { | @@ -25,7 +37,7 @@ typedef const struct { | ||
25 | uint32_t dc2; | 37 | uint32_t dc2; |
26 | uint32_t dc3; | 38 | uint32_t dc3; |
27 | uint32_t dc4; | 39 | uint32_t dc4; |
28 | - enum {OLED_I2C, OLED_SSI} oled; | 40 | + uint32_t peripherals; |
29 | } stellaris_board_info; | 41 | } stellaris_board_info; |
30 | 42 | ||
31 | /* General purpose timer module. */ | 43 | /* General purpose timer module. */ |
@@ -991,7 +1003,7 @@ static stellaris_board_info stellaris_boards[] = { | @@ -991,7 +1003,7 @@ static stellaris_board_info stellaris_boards[] = { | ||
991 | 0x01071013, | 1003 | 0x01071013, |
992 | 0x3f0f01ff, | 1004 | 0x3f0f01ff, |
993 | 0x0000001f, | 1005 | 0x0000001f, |
994 | - OLED_I2C | 1006 | + BP_OLED_I2C |
995 | }, | 1007 | }, |
996 | { "LM3S6965EVB", | 1008 | { "LM3S6965EVB", |
997 | 0x10010002, | 1009 | 0x10010002, |
@@ -1001,7 +1013,7 @@ static stellaris_board_info stellaris_boards[] = { | @@ -1001,7 +1013,7 @@ static stellaris_board_info stellaris_boards[] = { | ||
1001 | 0x030f5317, | 1013 | 0x030f5317, |
1002 | 0x0f0f87ff, | 1014 | 0x0f0f87ff, |
1003 | 0x5000007f, | 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,7 +1064,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, | ||
1052 | if (board->dc2 & (1 << 12)) { | 1064 | if (board->dc2 & (1 << 12)) { |
1053 | i2c = i2c_init_bus(); | 1065 | i2c = i2c_init_bus(); |
1054 | stellaris_i2c_init(0x40020000, pic[8], i2c); | 1066 | stellaris_i2c_init(0x40020000, pic[8], i2c); |
1055 | - if (board->oled == OLED_I2C) { | 1067 | + if (board->peripherals & BP_OLED_I2C) { |
1056 | ssd0303_init(ds, i2c, 0x3d); | 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,15 +1076,27 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, | ||
1064 | } | 1076 | } |
1065 | } | 1077 | } |
1066 | if (board->dc2 & (1 << 4)) { | 1078 | if (board->dc2 & (1 << 4)) { |
1067 | - if (board->oled == OLED_SSI) { | 1079 | + if (board->peripherals & BP_OLED_SSI) { |
1068 | void * oled; | 1080 | void * oled; |
1069 | /* FIXME: Implement chip select for OLED/MMC. */ | 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 | pl022_init(0x40008000, pic[7], ssd0323_xfer_ssi, oled); | 1083 | pl022_init(0x40008000, pic[7], ssd0323_xfer_ssi, oled); |
1072 | } else { | 1084 | } else { |
1073 | pl022_init(0x40008000, pic[7], NULL, NULL); | 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 | /* FIXME: Figure out how to generate these from stellaris_boards. */ | 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 | + |