source: mainline/uspace/srv/hid/input/port/chardev.c

Last change on this file was 7348c4b, checked in by Jakub Jermář <jakub@…>, 6 years ago

arm64: Add PL011 uspace driver

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*
2 * Copyright (c) 2011 Jiri Svoboda
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 input
31 * @{
32 */
33/** @file
34 * @brief Chardev keyboard port driver.
35 */
36
37#include <async.h>
38#include <errno.h>
39#include <fibril.h>
40#include <io/chardev.h>
41#include <loc.h>
42#include <stdio.h>
43#include "../input.h"
44#include "../kbd_port.h"
45#include "../kbd.h"
46
47static errno_t kbd_port_fibril(void *);
48
49static errno_t chardev_port_init(kbd_dev_t *);
50static void chardev_port_write(uint8_t);
51
52kbd_port_ops_t chardev_port = {
53 .init = chardev_port_init,
54 .write = chardev_port_write
55};
56
57static kbd_dev_t *kbd_dev;
58static async_sess_t *dev_sess;
59static chardev_t *chardev;
60
61/** List of devices to try connecting to. */
62static const char *in_devs[] = {
63 /** S3C24xx UART - Openmoko debug console */
64 "char/s3c24xx_uart",
65 /** Ski console, MSIM console, Sun4v console */
66 "devices/\\hw\\console\\a",
67 /** PL011 serial console */
68 "devices/\\hw\\uart\\a"
69};
70
71static const unsigned int num_devs = sizeof(in_devs) / sizeof(in_devs[0]);
72
73static errno_t chardev_port_init(kbd_dev_t *kdev)
74{
75 service_id_t service_id;
76 unsigned int i;
77 fid_t fid;
78 errno_t rc;
79
80 kbd_dev = kdev;
81again:
82 for (i = 0; i < num_devs; i++) {
83 rc = loc_service_get_id(in_devs[i], &service_id, 0);
84 if (rc == EOK)
85 break;
86 }
87
88 if (i >= num_devs) {
89 /* XXX This is just a hack. */
90 printf("%s: No input device found, sleep for retry.\n", NAME);
91 fibril_usleep(1000 * 1000);
92 goto again;
93 }
94
95 dev_sess = loc_service_connect(service_id, INTERFACE_DDF,
96 IPC_FLAG_BLOCKING);
97 if (dev_sess == NULL) {
98 printf("%s: Failed connecting to device\n", NAME);
99 return ENOENT;
100 }
101
102 rc = chardev_open(dev_sess, &chardev);
103 if (rc != EOK) {
104 printf("%s: Failed opening character device\n", NAME);
105 async_hangup(dev_sess);
106 return ENOMEM;
107 }
108
109 fid = fibril_create(kbd_port_fibril, NULL);
110 if (fid == 0) {
111 printf("%s: Failed creating fibril\n", NAME);
112 chardev_close(chardev);
113 async_hangup(dev_sess);
114 return ENOMEM;
115 }
116
117 fibril_add_ready(fid);
118
119 printf("%s: Found input device '%s'\n", NAME, in_devs[i]);
120 return 0;
121}
122
123static void chardev_port_write(uint8_t data)
124{
125 errno_t rc;
126 size_t nwr;
127
128 rc = chardev_write(chardev, &data, sizeof(data), &nwr);
129 if (rc != EOK || nwr != sizeof(data)) {
130 printf("%s: Failed writing to character device\n", NAME);
131 return;
132 }
133}
134
135static errno_t kbd_port_fibril(void *arg)
136{
137 errno_t rc;
138 size_t nread;
139 uint8_t b;
140
141 while (true) {
142 rc = chardev_read(chardev, &b, sizeof(b), &nread,
143 chardev_f_none);
144 if (rc != EOK || nread != sizeof(b)) {
145 printf("%s: Error reading data", NAME);
146 continue;
147 }
148
149 kbd_push_data(kbd_dev, b);
150 }
151
152 return 0;
153}
154
155/**
156 * @}
157 */
Note: See TracBrowser for help on using the repository browser.