Changeset 0f74869 in mainline for kernel/genarch/src/kbd/z8530.c
- Timestamp:
- 2009-02-22T15:20:43Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f9f9a13
- Parents:
- e7abb0e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/kbd/z8530.c
re7abb0e r0f74869 32 32 /** 33 33 * @file 34 * @brief Zilog 8530 serial port / keyboarddriver.34 * @brief Zilog 8530 serial port driver. 35 35 */ 36 36 … … 39 39 #include <genarch/kbd/scanc.h> 40 40 #include <genarch/kbd/scanc_sun.h> 41 #include <arch/drivers/z8530.h> 41 #include <arch/drivers/kbd.h> 42 #include <console/console.h> 43 #include <console/chardev.h> 44 #include <sysinfo/sysinfo.h> 42 45 #include <ddi/irq.h> 43 #include <ipc/irq.h>44 #include <arch/interrupt.h>45 #include <arch/drivers/kbd.h>46 #include <cpu.h>47 46 #include <arch/asm.h> 48 #include <arch.h> 49 #include <console/chardev.h> 50 #include <console/console.h> 51 #include <interrupt.h> 52 #include <sysinfo/sysinfo.h> 53 #include <print.h> 47 #include <mm/slab.h> 48 49 static inline void z8530_write(ioport8_t *ctl, uint8_t reg, uint8_t val) 50 { 51 /* 52 * Registers 8-15 will automatically issue the Point High 53 * command as their bit 3 is 1. 54 */ 55 pio_write_8(ctl, reg); /* select register */ 56 pio_write_8(ctl, val); /* write value */ 57 } 58 59 static inline uint8_t z8530_read(ioport8_t *ctl, uint8_t reg) 60 { 61 /* 62 * Registers 8-15 will automatically issue the Point High 63 * command as their bit 3 is 1. 64 */ 65 pio_write_8(ctl, reg); /* select register */ 66 return pio_read_8(ctl); 67 } 54 68 55 69 /* … … 57 71 */ 58 72 #define IGNORE_CODE 0x7f /* all keys up */ 59 60 static z8530_t z8530; /**< z8530 device structure. */61 static irq_t z8530_irq; /**< z8530's IRQ. */62 73 63 74 static void z8530_suspend(chardev_t *); … … 67 78 .suspend = z8530_suspend, 68 79 .resume = z8530_resume, 69 .read = z8530_key_read70 80 }; 71 81 72 /** Initialize keyboard and service interrupts using kernel routine. */ 73 void z8530_grab(void) 82 /** Initialize z8530. */ 83 bool 84 z8530_init(z8530_t *dev, devno_t devno, inr_t inr, cir_t cir, void *cir_arg) 74 85 { 75 ipl_t ipl = interrupts_disable();86 z8530_instance_t *instance; 76 87 77 (void) z8530_read_a(&z8530, RR8); 88 chardev_initialize("z8530_kbd", &kbrd, &ops); 89 stdin = &kbrd; 90 91 instance = malloc(sizeof(z8530_instance_t), FRAME_ATOMIC); 92 if (!instance) 93 return false; 94 95 instance->devno = devno; 96 instance->z8530 = dev; 97 98 irq_initialize(&instance->irq); 99 instance->irq.devno = devno; 100 instance->irq.inr = inr; 101 instance->irq.claim = z8530_claim; 102 instance->irq.handler = z8530_irq_handler; 103 instance->irq.instance = instance; 104 instance->irq.cir = cir; 105 instance->irq.cir_arg = cir_arg; 106 irq_register(&instance->irq); 107 108 (void) z8530_read(&dev->ctl_a, RR8); 78 109 79 110 /* … … 81 112 * to set FHC UART interrupt state to idle. 82 113 */ 83 z8530_write _a(&z8530, WR0, WR0_TX_IP_RST);114 z8530_write(&dev->ctl_a, WR0, WR0_TX_IP_RST); 84 115 85 116 /* interrupt on all characters */ 86 z8530_write _a(&z8530, WR1, WR1_IARCSC);117 z8530_write(&dev->ctl_a, WR1, WR1_IARCSC); 87 118 88 119 /* 8 bits per character and enable receiver */ 89 z8530_write _a(&z8530, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE);120 z8530_write(&dev->ctl_a, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE); 90 121 91 122 /* Master Interrupt Enable. */ 92 z8530_write_a(&z8530, WR9, WR9_MIE); 93 94 spinlock_lock(&z8530_irq.lock); 95 z8530_irq.notif_cfg.notify = false; 96 spinlock_unlock(&z8530_irq.lock); 97 interrupts_restore(ipl); 98 } 123 z8530_write(&dev->ctl_a, WR9, WR9_MIE); 99 124 100 /** Resume the former IPC notification behavior. */ 101 void z8530_release(void) 102 { 103 ipl_t ipl = interrupts_disable(); 104 spinlock_lock(&z8530_irq.lock); 105 if (z8530_irq.notif_cfg.answerbox) 106 z8530_irq.notif_cfg.notify = true; 107 spinlock_unlock(&z8530_irq.lock); 108 interrupts_restore(ipl); 109 } 110 111 /** Initialize z8530. */ 112 void 113 z8530_init(devno_t devno, uintptr_t vaddr, inr_t inr, cir_t cir, void *cir_arg) 114 { 115 chardev_initialize("z8530_kbd", &kbrd, &ops); 116 stdin = &kbrd; 117 118 z8530.devno = devno; 119 z8530.reg = (uint8_t *) vaddr; 120 121 irq_initialize(&z8530_irq); 122 z8530_irq.devno = devno; 123 z8530_irq.inr = inr; 124 z8530_irq.claim = z8530_claim; 125 z8530_irq.handler = z8530_irq_handler; 126 z8530_irq.cir = cir; 127 z8530_irq.cir_arg = cir_arg; 128 irq_register(&z8530_irq); 129 125 /* 126 * This is the necessary evil until the userspace drivers are entirely 127 * self-sufficient. 128 */ 130 129 sysinfo_set_item_val("kbd", NULL, true); 131 130 sysinfo_set_item_val("kbd.type", NULL, KBD_Z8530); 132 131 sysinfo_set_item_val("kbd.devno", NULL, devno); 133 132 sysinfo_set_item_val("kbd.inr", NULL, inr); 134 sysinfo_set_item_val("kbd.address.virtual", NULL, vaddr);133 sysinfo_set_item_val("kbd.address.virtual", NULL, (uintptr_t) dev); 135 134 136 z8530_grab(); 137 } 138 139 /** Process z8530 interrupt. 140 * 141 * @param n Interrupt vector. 142 * @param istate Interrupted state. 143 */ 144 void z8530_interrupt(void) 145 { 146 z8530_poll(); 135 return true; 147 136 } 148 137 … … 157 146 } 158 147 159 char z8530_key_read(chardev_t *d)148 irq_ownership_t z8530_claim(irq_t *irq) 160 149 { 161 char ch; 150 z8530_instance_t *instance = irq->instance; 151 z8530_t *dev = instance->z8530; 162 152 163 while(!(ch = active_read_buff_read())) { 164 uint8_t x; 165 while (!(z8530_read_a(&z8530, RR0) & RR0_RCA)) 166 ; 167 x = z8530_read_a(&z8530, RR8); 168 if (x != IGNORE_CODE) { 169 if (x & KEY_RELEASE) 170 key_released(x ^ KEY_RELEASE); 171 else 172 active_read_key_pressed(x); 173 } 174 } 175 return ch; 153 return (z8530_read(&dev->ctl_a, RR0) & RR0_RCA); 176 154 } 177 155 178 /** Poll for key press and release events. 179 * 180 * This function can be used to implement keyboard polling. 181 */ 182 void z8530_poll(void) 156 void z8530_irq_handler(irq_t *irq) 183 157 { 158 z8530_instance_t *instance = irq->instance; 159 z8530_t *dev = instance->z8530; 184 160 uint8_t x; 185 161 186 while (z8530_read_a(&z8530, RR0) & RR0_RCA) {187 x = z8530_read _a(&z8530, RR8);162 if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA) { 163 x = z8530_read(&dev->ctl_a, RR8); 188 164 if (x != IGNORE_CODE) { 189 165 if (x & KEY_RELEASE) … … 195 171 } 196 172 197 irq_ownership_t z8530_claim(irq_t *irq)198 {199 return (z8530_read_a(&z8530, RR0) & RR0_RCA);200 }201 202 void z8530_irq_handler(irq_t *irq)203 {204 if (irq->notif_cfg.notify && irq->notif_cfg.answerbox)205 ipc_irq_send_notif(irq);206 else207 z8530_interrupt();208 }209 210 173 /** @} 211 174 */
Note:
See TracChangeset
for help on using the changeset viewer.