?? spitz.c
字號:
s->pre_map[0x09 | SHIFT ] = 0x24 | FN; /* asterisk */ s->pre_map[0x2b ] = 0x25 | FN; /* backslash */ s->pre_map[0x2b | SHIFT ] = 0x26 | FN; /* bar */ s->pre_map[0x0c | SHIFT ] = 0x30 | FN; /* underscore */ s->pre_map[0x33 | SHIFT ] = 0x33 | FN; /* less */ s->pre_map[0x35 ] = 0x33 | SHIFT; /* slash */ s->pre_map[0x34 | SHIFT ] = 0x34 | FN; /* greater */ s->pre_map[0x35 | SHIFT ] = 0x34 | SHIFT; /* question */ s->pre_map[0x49 ] = 0x48 | FN; /* Page_Up */ s->pre_map[0x51 ] = 0x50 | FN; /* Page_Down */ s->modifiers = 0; s->imodifiers = 0; s->fifopos = 0; s->fifolen = 0; s->kbdtimer = qemu_new_timer(vm_clock, spitz_keyboard_tick, s); spitz_keyboard_tick(s);}#undef SHIFT#undef CTRL#undef FNstatic void spitz_keyboard_save(QEMUFile *f, void *opaque){ struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque; int i; qemu_put_be16s(f, &s->sense_state); qemu_put_be16s(f, &s->strobe_state); for (i = 0; i < 5; i ++) qemu_put_byte(f, spitz_gpio_invert[i]);}static int spitz_keyboard_load(QEMUFile *f, void *opaque, int version_id){ struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque; int i; qemu_get_be16s(f, &s->sense_state); qemu_get_be16s(f, &s->strobe_state); for (i = 0; i < 5; i ++) spitz_gpio_invert[i] = qemu_get_byte(f); /* Release all pressed keys */ memset(s->keyrow, 0, sizeof(s->keyrow)); spitz_keyboard_sense_update(s); s->modifiers = 0; s->imodifiers = 0; s->fifopos = 0; s->fifolen = 0; return 0;}static void spitz_keyboard_register(struct pxa2xx_state_s *cpu){ int i, j; struct spitz_keyboard_s *s; s = (struct spitz_keyboard_s *) qemu_mallocz(sizeof(struct spitz_keyboard_s)); memset(s, 0, sizeof(struct spitz_keyboard_s)); for (i = 0; i < 0x80; i ++) s->keymap[i] = -1; for (i = 0; i < SPITZ_KEY_SENSE_NUM + 1; i ++) for (j = 0; j < SPITZ_KEY_STROBE_NUM; j ++) if (spitz_keymap[i][j] != -1) s->keymap[spitz_keymap[i][j]] = (i << 4) | j; for (i = 0; i < SPITZ_KEY_SENSE_NUM; i ++) s->sense[i] = pxa2xx_gpio_in_get(cpu->gpio)[spitz_gpio_key_sense[i]]; for (i = 0; i < 5; i ++) s->gpiomap[i] = pxa2xx_gpio_in_get(cpu->gpio)[spitz_gpiomap[i]]; s->strobe = qemu_allocate_irqs(spitz_keyboard_strobe, s, SPITZ_KEY_STROBE_NUM); for (i = 0; i < SPITZ_KEY_STROBE_NUM; i ++) pxa2xx_gpio_out_set(cpu->gpio, spitz_gpio_key_strobe[i], s->strobe[i]); spitz_keyboard_pre_map(s); qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s); register_savevm("spitz_keyboard", 0, 0, spitz_keyboard_save, spitz_keyboard_load, s);}/* SCOOP devices */struct scoop_info_s { target_phys_addr_t target_base; qemu_irq handler[16]; qemu_irq *in; uint16_t status; uint16_t power; uint32_t gpio_level; uint32_t gpio_dir; uint32_t prev_level; uint16_t mcr; uint16_t cdr; uint16_t ccr; uint16_t irr; uint16_t imr; uint16_t isr; uint16_t gprr;};#define SCOOP_MCR 0x00#define SCOOP_CDR 0x04#define SCOOP_CSR 0x08#define SCOOP_CPR 0x0c#define SCOOP_CCR 0x10#define SCOOP_IRR_IRM 0x14#define SCOOP_IMR 0x18#define SCOOP_ISR 0x1c#define SCOOP_GPCR 0x20#define SCOOP_GPWR 0x24#define SCOOP_GPRR 0x28static inline void scoop_gpio_handler_update(struct scoop_info_s *s) { uint32_t level, diff; int bit; level = s->gpio_level & s->gpio_dir; for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { bit = ffs(diff) - 1; qemu_set_irq(s->handler[bit], (level >> bit) & 1); } s->prev_level = level;}static uint32_t scoop_readb(void *opaque, target_phys_addr_t addr){ struct scoop_info_s *s = (struct scoop_info_s *) opaque; addr -= s->target_base; switch (addr) { case SCOOP_MCR: return s->mcr; case SCOOP_CDR: return s->cdr; case SCOOP_CSR: return s->status; case SCOOP_CPR: return s->power; case SCOOP_CCR: return s->ccr; case SCOOP_IRR_IRM: return s->irr; case SCOOP_IMR: return s->imr; case SCOOP_ISR: return s->isr; case SCOOP_GPCR: return s->gpio_dir; case SCOOP_GPWR: return s->gpio_level; case SCOOP_GPRR: return s->gprr; default: spitz_printf("Bad register offset " REG_FMT "\n", addr); } return 0;}static void scoop_writeb(void *opaque, target_phys_addr_t addr, uint32_t value){ struct scoop_info_s *s = (struct scoop_info_s *) opaque; addr -= s->target_base; value &= 0xffff; switch (addr) { case SCOOP_MCR: s->mcr = value; break; case SCOOP_CDR: s->cdr = value; break; case SCOOP_CPR: s->power = value; if (value & 0x80) s->power |= 0x8040; break; case SCOOP_CCR: s->ccr = value; break; case SCOOP_IRR_IRM: s->irr = value; break; case SCOOP_IMR: s->imr = value; break; case SCOOP_ISR: s->isr = value; break; case SCOOP_GPCR: s->gpio_dir = value; scoop_gpio_handler_update(s); break; case SCOOP_GPWR: s->gpio_level = value & s->gpio_dir; scoop_gpio_handler_update(s); break; case SCOOP_GPRR: s->gprr = value; break; default: spitz_printf("Bad register offset " REG_FMT "\n", addr); }}CPUReadMemoryFunc *scoop_readfn[] = { scoop_readb, scoop_readb, scoop_readb,};CPUWriteMemoryFunc *scoop_writefn[] = { scoop_writeb, scoop_writeb, scoop_writeb,};static void scoop_gpio_set(void *opaque, int line, int level){ struct scoop_info_s *s = (struct scoop_info_s *) s; if (level) s->gpio_level |= (1 << line); else s->gpio_level &= ~(1 << line);}static inline qemu_irq *scoop_gpio_in_get(struct scoop_info_s *s){ return s->in;}static inline void scoop_gpio_out_set(struct scoop_info_s *s, int line, qemu_irq handler) { if (line >= 16) { spitz_printf("No GPIO pin %i\n", line); return; } s->handler[line] = handler;}static void scoop_save(QEMUFile *f, void *opaque){ struct scoop_info_s *s = (struct scoop_info_s *) opaque; qemu_put_be16s(f, &s->status); qemu_put_be16s(f, &s->power); qemu_put_be32s(f, &s->gpio_level); qemu_put_be32s(f, &s->gpio_dir); qemu_put_be32s(f, &s->prev_level); qemu_put_be16s(f, &s->mcr); qemu_put_be16s(f, &s->cdr); qemu_put_be16s(f, &s->ccr); qemu_put_be16s(f, &s->irr); qemu_put_be16s(f, &s->imr); qemu_put_be16s(f, &s->isr); qemu_put_be16s(f, &s->gprr);}static int scoop_load(QEMUFile *f, void *opaque, int version_id){ struct scoop_info_s *s = (struct scoop_info_s *) opaque; qemu_get_be16s(f, &s->status); qemu_get_be16s(f, &s->power); qemu_get_be32s(f, &s->gpio_level); qemu_get_be32s(f, &s->gpio_dir); qemu_get_be32s(f, &s->prev_level); qemu_get_be16s(f, &s->mcr); qemu_get_be16s(f, &s->cdr); qemu_get_be16s(f, &s->ccr); qemu_get_be16s(f, &s->irr); qemu_get_be16s(f, &s->imr); qemu_get_be16s(f, &s->isr); qemu_get_be16s(f, &s->gprr); return 0;}static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu, int count) { int iomemtype; struct scoop_info_s *s; s = (struct scoop_info_s *) qemu_mallocz(sizeof(struct scoop_info_s) * 2); memset(s, 0, sizeof(struct scoop_info_s) * count); s[0].target_base = 0x10800000; s[1].target_base = 0x08800040; /* Ready */ s[0].status = 0x02; s[1].status = 0x02; s[0].in = qemu_allocate_irqs(scoop_gpio_set, &s[0], 16); iomemtype = cpu_register_io_memory(0, scoop_readfn, scoop_writefn, &s[0]); cpu_register_physical_memory(s[0].target_base, 0x1000, iomemtype); register_savevm("scoop", 0, 0, scoop_save, scoop_load, &s[0]); if (count < 2) return s; s[1].in = qemu_allocate_irqs(scoop_gpio_set, &s[1], 16); iomemtype = cpu_register_io_memory(0, scoop_readfn, scoop_writefn, &s[1]); cpu_register_physical_memory(s[1].target_base, 0x1000, iomemtype); register_savevm("scoop", 1, 0, scoop_save, scoop_load, &s[1]); return s;}/* LCD backlight controller */#define LCDTG_RESCTL 0x00#define LCDTG_PHACTRL 0x01#define LCDTG_DUTYCTRL 0x02#define LCDTG_POWERREG0 0x03#define LCDTG_POWERREG1 0x04#define LCDTG_GPOR3 0x05#define LCDTG_PICTRL 0x06#define LCDTG_POLCTRL 0x07static int bl_intensity, bl_power;static void spitz_bl_update(struct pxa2xx_state_s *s){ if (bl_power && bl_intensity) spitz_printf("LCD Backlight now at %i/63\n", bl_intensity); else spitz_printf("LCD Backlight now off\n");}static inline void spitz_bl_bit5(void *opaque, int line, int level){ int prev = bl_intensity; if (level) bl_intensity &= ~0x20; else bl_intensity |= 0x20; if (bl_power && prev != bl_intensity) spitz_bl_update((struct pxa2xx_state_s *) opaque);}static inline void spitz_bl_power(void *opaque, int line, int level){ bl_power = !!level; spitz_bl_update((struct pxa2xx_state_s *) opaque);}static void spitz_lcdtg_dac_put(void *opaque, uint8_t cmd){ int addr, value; addr = cmd >> 5; value = cmd & 0x1f; switch (addr) { case LCDTG_RESCTL: if (value) spitz_printf("LCD in QVGA mode\n"); else spitz_printf("LCD in VGA mode\n"); break; case LCDTG_DUTYCTRL: bl_intensity &= ~0x1f; bl_intensity |= value; if (bl_power) spitz_bl_update((struct pxa2xx_state_s *) opaque); break; case LCDTG_POWERREG0: /* Set common voltage to M62332FP */ break; }}/* SSP devices */#define CORGI_SSP_PORT 2#define SPITZ_GPIO_LCDCON_CS 53#define SPITZ_GPIO_ADS7846_CS 14#define SPITZ_GPIO_MAX1111_CS 20#define SPITZ_GPIO_TP_INT 11static int lcd_en, ads_en, max_en;static struct max111x_s *max1111;static struct ads7846_state_s *ads7846;/* "Demux" the signal based on current chipselect */static uint32_t corgi_ssp_read(void *opaque){ if (lcd_en) return 0; if (ads_en) return ads7846_read(ads7846); if (max_en) return max111x_read(max1111); return 0;}static void corgi_ssp_write(void *opaque, uint32_t value){ if (lcd_en) spitz_lcdtg_dac_put(opaque, value); if (ads_en) ads7846_write(ads7846, value); if (max_en) max111x_write(max1111, value);}static void corgi_ssp_gpio_cs(void *opaque, int line, int level){ switch (line) { case 0: lcd_en = !level; break; case 1: ads_en = !level; break; case 2:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -