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