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   NS 16550 serial port / keyboard driver.
34
 * @brief   NS 16550 serial controller driver.
35
 */
35
 */
36
 
36
 
37
#include <genarch/kbd/ns16550.h>
37
#include <genarch/drivers/ns16550/ns16550.h>
38
#include <genarch/kbd/key.h>
-
 
39
#include <genarch/kbd/scanc.h>
-
 
40
#include <genarch/kbd/scanc_sun.h>
-
 
41
#include <arch/drivers/kbd.h>
-
 
42
#include <ddi/irq.h>
38
#include <ddi/irq.h>
43
#include <cpu.h>
-
 
44
#include <arch/asm.h>
39
#include <arch/asm.h>
45
#include <arch.h>
-
 
46
#include <console/chardev.h>
40
#include <console/chardev.h>
47
#include <console/console.h>
-
 
48
#include <interrupt.h>
-
 
49
#include <arch/interrupt.h>
-
 
50
#include <synch/spinlock.h>
-
 
51
#include <mm/slab.h>
41
#include <mm/slab.h>
52
 
42
 
53
#define LSR_DATA_READY  0x01
43
#define LSR_DATA_READY  0x01
54
 
44
 
55
/*
-
 
56
 * These codes read from ns16550 data register are silently ignored.
-
 
57
 */
-
 
58
#define IGNORE_CODE 0x7f        /* all keys up */
-
 
59
 
-
 
60
static void ns16550_suspend(chardev_t *);
-
 
61
static void ns16550_resume(chardev_t *);
-
 
62
 
-
 
63
static chardev_operations_t ops = {
-
 
64
    .suspend = ns16550_suspend,
-
 
65
    .resume = ns16550_resume,
-
 
66
};
-
 
67
 
-
 
68
/** Initialize ns16550.
45
/** Initialize ns16550.
69
 *
46
 *
70
 * @param dev       Addrress of the beginning of the device in I/O space.
47
 * @param dev       Addrress of the beginning of the device in I/O space.
71
 * @param devno     Device number.
48
 * @param devno     Device number.
72
 * @param inr       Interrupt number.
49
 * @param inr       Interrupt number.
73
 * @param cir       Clear interrupt function.
50
 * @param cir       Clear interrupt function.
74
 * @param cir_arg   First argument to cir.
51
 * @param cir_arg   First argument to cir.
-
 
52
 * @param devout    Output character device.
75
 *
53
 *
76
 * @return      True on success, false on failure.
54
 * @return      True on success, false on failure.
77
 */
55
 */
78
bool
56
bool
79
ns16550_init(ns16550_t *dev, devno_t devno, inr_t inr, cir_t cir, void *cir_arg)
57
ns16550_init(ns16550_t *dev, devno_t devno, inr_t inr, cir_t cir, void *cir_arg,
-
 
58
    chardev_t *devout)
80
{
59
{
81
    ns16550_instance_t *instance;
60
    ns16550_instance_t *instance;
82
 
-
 
83
    chardev_initialize("ns16550_kbd", &kbrd, &ops);
-
 
84
    stdin = &kbrd;
-
 
85
   
61
   
86
    instance = malloc(sizeof(ns16550_instance_t), FRAME_ATOMIC);
62
    instance = malloc(sizeof(ns16550_instance_t), FRAME_ATOMIC);
87
    if (!instance)
63
    if (!instance)
88
        return false;
64
        return false;
89
 
65
 
90
    instance->devno = devno;
66
    instance->devno = devno;
91
    instance->ns16550 = dev;
67
    instance->ns16550 = dev;
-
 
68
    instance->devout = devout;
92
   
69
   
93
    irq_initialize(&instance->irq);
70
    irq_initialize(&instance->irq);
94
    instance->irq.devno = devno;
71
    instance->irq.devno = devno;
95
    instance->irq.inr = inr;
72
    instance->irq.inr = inr;
96
    instance->irq.claim = ns16550_claim;
73
    instance->irq.claim = ns16550_claim;
Line 108... Line 85...
108
    pio_write_8(&dev->mcr, MCR_OUT2);
85
    pio_write_8(&dev->mcr, MCR_OUT2);
109
   
86
   
110
    return true;
87
    return true;
111
}
88
}
112
 
89
 
113
/* Called from getc(). */
-
 
114
void ns16550_resume(chardev_t *d)
-
 
115
{
-
 
116
}
-
 
117
 
-
 
118
/* Called from getc(). */
-
 
119
void ns16550_suspend(chardev_t *d)
-
 
120
{
-
 
121
}
-
 
122
 
-
 
123
irq_ownership_t ns16550_claim(irq_t *irq)
90
irq_ownership_t ns16550_claim(irq_t *irq)
124
{
91
{
125
    ns16550_instance_t *ns16550_instance = irq->instance;
92
    ns16550_instance_t *instance = irq->instance;
126
    ns16550_t *dev = ns16550_instance->ns16550;
93
    ns16550_t *dev = instance->ns16550;
127
 
94
 
128
    if (pio_read_8(&dev->lsr) & LSR_DATA_READY)
95
    if (pio_read_8(&dev->lsr) & LSR_DATA_READY)
129
        return IRQ_ACCEPT;
96
        return IRQ_ACCEPT;
130
    else
97
    else
131
        return IRQ_DECLINE;
98
        return IRQ_DECLINE;
132
}
99
}
133
 
100
 
134
void ns16550_irq_handler(irq_t *irq)
101
void ns16550_irq_handler(irq_t *irq)
135
{
102
{
136
    ns16550_instance_t *ns16550_instance = irq->instance;
103
    ns16550_instance_t *instance = irq->instance;
137
    ns16550_t *dev = ns16550_instance->ns16550;
104
    ns16550_t *dev = instance->ns16550;
138
 
105
 
139
    if (pio_read_8(&dev->lsr) & LSR_DATA_READY) {
106
    if (pio_read_8(&dev->lsr) & LSR_DATA_READY) {
140
        uint8_t x;
107
        uint8_t x;
141
       
108
       
142
        x = pio_read_8(&dev->rbr);
109
        x = pio_read_8(&dev->rbr);
143
       
-
 
144
        if (x != IGNORE_CODE) {
-
 
145
            if (x & KEY_RELEASE)
110
        if (instance->devout)
146
                key_released(x ^ KEY_RELEASE);
111
            chardev_push_character(instance->devout, x);
147
            else
-
 
148
                key_pressed(x);
-
 
149
        }
-
 
150
    }
112
    }
151
 
-
 
152
}
113
}
153
 
114
 
154
/** @}
115
/** @}
155
 */
116
 */