Subversion Repositories HelenOS

Rev

Rev 3982 | Rev 4094 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3982 Rev 4042
Line 29... Line 29...
29
/** @addtogroup genarch
29
/** @addtogroup genarch
30
 * @{
30
 * @{
31
 */
31
 */
32
/**
32
/**
33
 * @file
33
 * @file
34
 * @brief   i8042 processor driver.
34
 * @brief   i8042 processor driver
35
 *
35
 *
36
 * It takes care of low-level keyboard functions.
36
 * It takes care of the i8042 serial communication.
37
 */
37
 */
38
 
38
 
39
#include <genarch/kbd/i8042.h>
39
#include <genarch/drivers/i8042/i8042.h>
40
#include <arch/drivers/kbd.h>
-
 
41
#include <genarch/kbd/key.h>
-
 
42
#include <genarch/kbd/scanc.h>
-
 
43
#include <genarch/kbd/scanc_pc.h>
-
 
44
#include <genarch/drivers/legacy/ia32/io.h>
40
#include <genarch/drivers/legacy/ia32/io.h>
45
#include <cpu.h>
-
 
46
#include <arch/asm.h>
41
#include <arch/asm.h>
47
#include <arch.h>
-
 
48
#include <console/chardev.h>
42
#include <console/chardev.h>
49
#include <console/console.h>
-
 
50
#include <interrupt.h>
43
#include <mm/slab.h>
51
 
-
 
52
/* Keyboard commands. */
-
 
53
#define KBD_ENABLE  0xf4
-
 
54
#define KBD_DISABLE 0xf5
-
 
55
#define KBD_ACK     0xfa
-
 
56
 
-
 
57
/*
-
 
58
 * 60  Write 8042 Command Byte: next data byte written to port 60h is
-
 
59
 *     placed in 8042 command register. Format:
-
 
60
 *
-
 
61
 *    |7|6|5|4|3|2|1|0|8042 Command Byte
-
 
62
 *     | | | | | | | `---- 1=enable output register full interrupt
-
 
63
 *     | | | | | | `----- should be 0
-
 
64
 *     | | | | | `------ 1=set status register system, 0=clear
-
 
65
 *     | | | | `------- 1=override keyboard inhibit, 0=allow inhibit
-
 
66
 *     | | | `-------- disable keyboard I/O by driving clock line low
-
 
67
 *     | | `--------- disable auxiliary device, drives clock line low
-
 
68
 *     | `---------- IBM scancode translation 0=AT, 1=PC/XT
-
 
69
 *     `----------- reserved, should be 0
-
 
70
 */
-
 
71
 
44
 
72
#define i8042_SET_COMMAND   0x60
45
#define i8042_SET_COMMAND   0x60
73
#define i8042_COMMAND       0x69
46
#define i8042_COMMAND       0x69
74
 
47
 
75
#define i8042_BUFFER_FULL_MASK  0x01
48
#define i8042_BUFFER_FULL_MASK  0x01
76
#define i8042_WAIT_MASK     0x02
49
#define i8042_WAIT_MASK     0x02
77
#define i8042_MOUSE_DATA    0x20
-
 
78
 
-
 
79
static void i8042_suspend(chardev_t *);
-
 
80
static void i8042_resume(chardev_t *);
-
 
81
 
-
 
82
static chardev_operations_t ops = {
-
 
83
    .suspend = i8042_suspend,
-
 
84
    .resume = i8042_resume,
-
 
85
};
-
 
86
 
50
 
87
static irq_ownership_t i8042_claim(irq_t *irq)
51
static irq_ownership_t i8042_claim(irq_t *irq)
88
{
52
{
89
    i8042_instance_t *i8042_instance = irq->instance;
53
    i8042_instance_t *i8042_instance = irq->instance;
90
    i8042_t *dev = i8042_instance->i8042;
54
    i8042_t *dev = i8042_instance->i8042;
Line 103... Line 67...
103
    uint8_t status;
67
    uint8_t status;
104
       
68
       
105
    if (((status = pio_read_8(&dev->status)) & i8042_BUFFER_FULL_MASK)) {
69
    if (((status = pio_read_8(&dev->status)) & i8042_BUFFER_FULL_MASK)) {
106
        data = pio_read_8(&dev->data);
70
        data = pio_read_8(&dev->data);
107
           
71
           
108
        if ((status & i8042_MOUSE_DATA))
-
 
109
            return;
-
 
110
 
-
 
111
        if (data & KEY_RELEASE)
72
        if (instance->devout)
112
            key_released(data ^ KEY_RELEASE);
73
            chardev_push_character(instance->devout, data);
113
        else
-
 
114
            key_pressed(data);
-
 
115
    }
74
    }
116
}
75
}
117
 
76
 
118
/** Initialize i8042. */
77
/** Initialize i8042. */
119
bool
78
bool
120
i8042_init(i8042_t *dev, devno_t devno, inr_t inr)
79
i8042_init(i8042_t *dev, devno_t devno, inr_t inr, chardev_t *devout)
121
{
80
{
122
    i8042_instance_t *instance;
81
    i8042_instance_t *instance;
123
 
82
 
124
    chardev_initialize("i8042_kbd", &kbrd, &ops);
-
 
125
    stdin = &kbrd;
-
 
126
   
-
 
127
    instance = malloc(sizeof(i8042_instance_t), FRAME_ATOMIC);
83
    instance = malloc(sizeof(i8042_instance_t), FRAME_ATOMIC);
128
    if (!instance)
84
    if (!instance)
129
        return false;
85
        return false;
130
   
86
   
131
    instance->devno = devno;
87
    instance->devno = devno;
132
    instance->i8042 = dev;
88
    instance->i8042 = dev;
-
 
89
    instance->devout = devout;
133
   
90
   
134
    irq_initialize(&instance->irq);
91
    irq_initialize(&instance->irq);
135
    instance->irq.devno = devno;
92
    instance->irq.devno = devno;
136
    instance->irq.inr = inr;
93
    instance->irq.inr = inr;
137
    instance->irq.claim = i8042_claim;
94
    instance->irq.claim = i8042_claim;
138
    instance->irq.handler = i8042_irq_handler;
95
    instance->irq.handler = i8042_irq_handler;
139
    instance->irq.instance = instance;
96
    instance->irq.instance = instance;
140
    irq_register(&instance->irq);
97
    irq_register(&instance->irq);
141
   
98
   
142
    trap_virtual_enable_irqs(1 << inr);
-
 
143
   
-
 
144
    /*
99
    /*
145
     * Clear input buffer.
100
     * Clear input buffer.
146
     */
101
     */
147
    while (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK)
102
    while (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK)
148
        (void) pio_read_8(&dev->data);
103
        (void) pio_read_8(&dev->data);
149
   
104
   
150
    return true;
105
    return true;
151
}
106
}
152
 
107
 
153
/* Called from getc(). */
-
 
154
void i8042_resume(chardev_t *d)
-
 
155
{
-
 
156
}
-
 
157
 
-
 
158
/* Called from getc(). */
-
 
159
void i8042_suspend(chardev_t *d)
-
 
160
{
-
 
161
}
-
 
162
 
-
 
163
/** @}
108
/** @}
164
 */
109
 */