Project

General

Profile

Statistics
| Branch: | Revision:

scoutos / prex-0.9.0 / bsp / drv / arm / gba / keypad.c @ 03e9c04a

History | View | Annotate | Download (3.63 KB)

1
/*-
2
 * Copyright (c) 2005-2009, Kohsuke Ohtani
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
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the author nor the names of any co-contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29

    
30
/*
31
 * keypad.c - GBA gamepad driver
32
 */
33

    
34
#include <driver.h>
35
#include <sys/keycode.h>
36
#include "swkbd.h"
37

    
38
/* Parameters */
39
#define KEYPAD_IRQ        12
40

    
41
/* Registers for gamepad control */
42
#define REG_KEYSTS        (*(volatile uint16_t *)0x4000130)
43
#define REG_KEYCNT        (*(volatile uint16_t *)0x4000132)
44

    
45
/* KEY_STS/KEY_CNT */
46
#define KEY_A                0x0001
47
#define KEY_B                0x0002
48
#define KEY_SELECT        0x0004
49
#define KEY_START        0x0008
50
#define KEY_RIGHT        0x0010
51
#define KEY_LEFT        0x0020
52
#define KEY_UP                0x0040
53
#define KEY_DOWN        0x0080
54
#define KEY_R                0x0100
55
#define KEY_L                0x0200
56

    
57
#define KEY_ALL                0x03ff
58

    
59
/* KEY_CNT value */
60
#define KEYIRQ_EN        0x4000        /* 0=Disable, 1=Enable */
61
#define KEYIRQ_COND        0x8000  /* 0=Logical OR, 1=Logical AND */
62

    
63

    
64
struct keypad_softc {
65
        device_t        dev;
66
        irq_t                irq;
67
};
68

    
69
static int keypad_init(struct driver *);
70

    
71
static struct devops keypad_devops = {
72
        /* open */        no_open,
73
        /* close */        no_close,
74
        /* read */        no_read,
75
        /* write */        no_write,
76
        /* ioctl */        no_ioctl,
77
        /* devctl */        no_devctl,
78
};
79

    
80
struct driver keypad_driver = {
81
        /* name */        "keypad",
82
        /* devops */        &keypad_devops,
83
        /* devsz */        sizeof(struct keypad_softc),
84
        /* flags */        0,
85
        /* probe */        NULL,
86
        /* init */        keypad_init,
87
        /* shutdown */        NULL,
88
};
89

    
90
/*
91
 * Interrupt service routine
92
 */
93
static int
94
keypad_isr(void *arg)
95
{
96
        uint16_t sts;
97

    
98
        sts = ~REG_KEYSTS & KEY_ALL;
99

    
100
        if (sts == (KEY_SELECT|KEY_START))
101
                machine_powerdown(PWR_REBOOT);
102

    
103
        if (sts & KEY_A)
104
                swkbd_input('A');
105
        if (sts & KEY_B)
106
                swkbd_input('B');
107
        if (sts & KEY_SELECT)
108
                swkbd_input('\t');
109
        if (sts & KEY_START)
110
                swkbd_input('\n');
111
        if (sts & KEY_RIGHT)
112
                swkbd_input(K_RGHT);
113
        if (sts & KEY_LEFT)
114
                swkbd_input(K_LEFT);
115
        if (sts & KEY_UP)
116
                swkbd_input(K_UP);
117
        if (sts & KEY_DOWN)
118
                swkbd_input(K_DOWN);
119
        if (sts & KEY_R)
120
                swkbd_input('R');
121
        if (sts & KEY_L)
122
                swkbd_input('L');
123

    
124
        return 0;
125
}
126

    
127
int
128
keypad_init(struct driver *self)
129
{
130
        struct keypad_softc *sc;
131
        device_t dev;
132

    
133
        dev = device_create(self, "keypad", D_CHR);
134
        sc = device_private(dev);
135

    
136
        /*
137
         * Setup isr
138
         */
139
        REG_KEYCNT = 0;        /* disable irq */
140
        sc->irq = irq_attach(KEYPAD_IRQ, IPL_INPUT, 0, keypad_isr,
141
                             IST_NONE, sc);
142
        REG_KEYCNT = KEY_ALL | KEYIRQ_EN;
143

    
144
        return 0;
145
}
146