source: mainline/uspace/srv/hid/input/port/sgcn.c@ 60e5a856

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 60e5a856 was 5f88293, checked in by Jiri Svoboda <jiri@…>, 14 years ago

Rename 'kbd' server to 'input' server.

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Copyright (c) 2008 Pavel Rimsky
3 * Copyright (c) 2011 Jiri Svoboda
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup kbd_port
31 * @ingroup kbd
32 * @{
33 */
34/** @file
35 * @brief SGCN (Serengeti Console) keyboard port driver.
36 */
37
38#include <as.h>
39#include <ddi.h>
40#include <async.h>
41#include <kbd.h>
42#include <kbd_port.h>
43#include <sysinfo.h>
44#include <stdio.h>
45#include <thread.h>
46#include <bool.h>
47#include <errno.h>
48
49static int sgcn_port_init(kbd_dev_t *);
50static void sgcn_port_yield(void);
51static void sgcn_port_reclaim(void);
52static void sgcn_port_write(uint8_t data);
53
54kbd_port_ops_t sgcn_port = {
55 .init = sgcn_port_init,
56 .yield = sgcn_port_yield,
57 .reclaim = sgcn_port_reclaim,
58 .write = sgcn_port_write
59};
60
61static kbd_dev_t *kbd_dev;
62
63#define POLL_INTERVAL 10000
64
65/**
66 * SGCN buffer header. It is placed at the very beginning of the SGCN
67 * buffer.
68 */
69typedef struct {
70 /** hard-wired to "CON" */
71 char magic[4];
72
73 /** we don't need this */
74 char unused[8];
75
76 /** offset within the SGCN buffer of the input buffer start */
77 uint32_t in_begin;
78
79 /** offset within the SGCN buffer of the input buffer end */
80 uint32_t in_end;
81
82 /** offset within the SGCN buffer of the input buffer read pointer */
83 uint32_t in_rdptr;
84
85 /** offset within the SGCN buffer of the input buffer write pointer */
86 uint32_t in_wrptr;
87} __attribute__ ((packed)) sgcn_buffer_header_t;
88
89/*
90 * Returns a pointer to the object of a given type which is placed at the given
91 * offset from the console buffer beginning.
92 */
93#define SGCN_BUFFER(type, offset) \
94 ((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
95
96/** Returns a pointer to the console buffer header. */
97#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0))
98
99/**
100 * Virtual address mapped to SRAM.
101 */
102static uintptr_t sram_virt_addr;
103
104/**
105 * SGCN buffer offset within SGCN.
106 */
107static uintptr_t sram_buffer_offset;
108
109/* polling thread */
110static void sgcn_thread_impl(void *arg);
111
112static volatile bool polling_disabled = false;
113
114/**
115 * Initializes the SGCN driver.
116 * Maps the physical memory (SRAM) and creates the polling thread.
117 */
118static int sgcn_port_init(kbd_dev_t *kdev)
119{
120 kbd_dev = kdev;
121
122 sysarg_t sram_paddr;
123 if (sysinfo_get_value("sram.address.physical", &sram_paddr) != EOK)
124 return -1;
125
126 sysarg_t sram_size;
127 if (sysinfo_get_value("sram.area.size", &sram_size) != EOK)
128 return -1;
129
130 if (sysinfo_get_value("sram.buffer.offset", &sram_buffer_offset) != EOK)
131 sram_buffer_offset = 0;
132
133 sram_virt_addr = (uintptr_t) as_get_mappable_page(sram_size);
134
135 if (physmem_map((void *) sram_paddr, (void *) sram_virt_addr,
136 sram_size / PAGE_SIZE, AS_AREA_READ | AS_AREA_WRITE) != 0) {
137 printf("SGCN: uspace driver could not map physical memory.");
138 return -1;
139 }
140
141 thread_id_t tid;
142 int rc = thread_create(sgcn_thread_impl, NULL, "kbd_poll", &tid);
143 if (rc != 0)
144 return rc;
145
146 return 0;
147}
148
149static void sgcn_port_yield(void)
150{
151 polling_disabled = true;
152}
153
154static void sgcn_port_reclaim(void)
155{
156 polling_disabled = false;
157}
158
159static void sgcn_port_write(uint8_t data)
160{
161 (void) data;
162}
163
164/**
165 * Handler of the "key pressed" event. Reads codes of all the pressed keys from
166 * the buffer.
167 */
168static void sgcn_key_pressed(void)
169{
170 char c;
171
172 uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
173 uint32_t end = SGCN_BUFFER_HEADER->in_end;
174 uint32_t size = end - begin;
175
176 volatile char *buf_ptr = (volatile char *)
177 SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
178 volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
179 volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
180
181 while (*in_rdptr_ptr != *in_wrptr_ptr) {
182 c = *buf_ptr;
183 *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
184 buf_ptr = (volatile char *)
185 SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
186 kbd_push_scancode(kbd_dev, c);
187 }
188}
189
190/**
191 * Thread to poll SGCN for keypresses.
192 */
193static void sgcn_thread_impl(void *arg)
194{
195 (void) arg;
196
197 while (1) {
198 if (polling_disabled == false)
199 sgcn_key_pressed();
200 usleep(POLL_INTERVAL);
201 }
202}
203
204/** @}
205 */
Note: See TracBrowser for help on using the repository browser.