Commit cf0dbb21156f2fabdbe8b846b16dfc9825d8b23c

Authored by pbrook
1 parent f090c9d4

Luminary board input support.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3689 c046a42c-6fe2-441c-8c8c-71466251a162
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 +