~galfy/helenos/bird-port-mainline

« back to all changes in this revision

Viewing changes to uspace/srv/kbd/port/ns16550.c

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2006 Josef Cejka
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *
 
9
 * - Redistributions of source code must retain the above copyright
 
10
 *   notice, this list of conditions and the following disclaimer.
 
11
 * - Redistributions in binary form must reproduce the above copyright
 
12
 *   notice, this list of conditions and the following disclaimer in the
 
13
 *   documentation and/or other materials provided with the distribution.
 
14
 * - The name of the author may not be used to endorse or promote products
 
15
 *   derived from this software without specific prior written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
/** @addtogroup kbd_port
 
30
 * @ingroup  kbd
 
31
 * @{
 
32
 */ 
 
33
/** @file
 
34
 * @brief       NS16550 port driver.
 
35
 */
 
36
 
 
37
#include <ipc/ipc.h>
 
38
#include <ipc/bus.h>
 
39
#include <async.h>
 
40
#include <sysinfo.h>
 
41
#include <kbd.h>
 
42
#include <kbd_port.h>
 
43
#include <sun.h>
 
44
#include <ddi.h>
 
45
 
 
46
/* NS16550 registers */
 
47
#define RBR_REG         0       /** Receiver Buffer Register. */
 
48
#define IER_REG         1       /** Interrupt Enable Register. */
 
49
#define IIR_REG         2       /** Interrupt Ident Register (read). */
 
50
#define FCR_REG         2       /** FIFO control register (write). */
 
51
#define LCR_REG         3       /** Line Control register. */
 
52
#define MCR_REG         4       /** Modem Control Register. */
 
53
#define LSR_REG         5       /** Line Status Register. */
 
54
 
 
55
#define LSR_DATA_READY  0x01
 
56
 
 
57
static irq_cmd_t ns16550_cmds[] = {
 
58
        {
 
59
                .cmd = CMD_PIO_READ_8,
 
60
                .addr = (void *) 0,     /* will be patched in run-time */
 
61
                .dstarg = 1
 
62
        },
 
63
        {
 
64
                .cmd = CMD_BTEST,
 
65
                .value = LSR_DATA_READY,
 
66
                .srcarg = 1,
 
67
                .dstarg = 3
 
68
        },
 
69
        {
 
70
                .cmd = CMD_PREDICATE,
 
71
                .value = 2,
 
72
                .srcarg = 3
 
73
        },
 
74
        {
 
75
                .cmd = CMD_PIO_READ_8,
 
76
                .addr = (void *) 0,     /* will be patched in run-time */
 
77
                .dstarg = 2
 
78
        },
 
79
        {
 
80
                .cmd = CMD_ACCEPT
 
81
        }
 
82
};
 
83
 
 
84
irq_code_t ns16550_kbd = {
 
85
        sizeof(ns16550_cmds) / sizeof(irq_cmd_t),
 
86
        ns16550_cmds
 
87
};
 
88
 
 
89
static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 
90
 
 
91
static uintptr_t ns16550_physical;
 
92
static uintptr_t ns16550_kernel; 
 
93
 
 
94
int ns16550_port_init(void)
 
95
{
 
96
        void *vaddr;
 
97
 
 
98
        async_set_interrupt_received(ns16550_irq_handler);
 
99
 
 
100
        ns16550_physical = sysinfo_value("kbd.address.physical");
 
101
        ns16550_kernel = sysinfo_value("kbd.address.kernel");
 
102
        ns16550_kbd.cmds[0].addr = (void *) (ns16550_kernel + LSR_REG);
 
103
        ns16550_kbd.cmds[3].addr = (void *) (ns16550_kernel + RBR_REG);
 
104
        ipc_register_irq(sysinfo_value("kbd.inr"), device_assign_devno(),
 
105
            sysinfo_value("kbd.inr"), &ns16550_kbd);
 
106
        return pio_enable((void *) ns16550_physical, 8, &vaddr);
 
107
}
 
108
 
 
109
void ns16550_port_yield(void)
 
110
{
 
111
}
 
112
 
 
113
void ns16550_port_reclaim(void)
 
114
{
 
115
}
 
116
 
 
117
static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call)
 
118
{
 
119
        int scan_code = IPC_GET_ARG2(*call);
 
120
        kbd_push_scancode(scan_code);
 
121
        
 
122
        if (cir_service)
 
123
                async_msg_1(cir_phone, BUS_CLEAR_INTERRUPT,
 
124
                    IPC_GET_METHOD(*call));
 
125
}
 
126
 
 
127
/**
 
128
 * @}
 
129
 */