source: mainline/uspace/drv/usbmouse/init.c@ dde8ca4

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since dde8ca4 was 21bb58d, checked in by Vojtech Horky <vojtechhorky@…>, 14 years ago

USB mouse sends events to console

The values are not properly scaled, the clicking is very simple
(doubt that the console is able to handle something more
complicated) but it is possible to switch consoles with the mouse.

Tested in QEMU only.

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Copyright (c) 2011 Vojtech Horky
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 drvusbmouse
30 * @{
31 */
32/**
33 * @file
34 * Initialization routines for USB mouse driver.
35 */
36#include "mouse.h"
37#include <usb/debug.h>
38#include <usb/classes/classes.h>
39#include <usb/classes/hid.h>
40#include <usb/request.h>
41#include <errno.h>
42
43/** Mouse polling endpoint description for boot protocol subclass. */
44static usb_endpoint_description_t poll_endpoint_description = {
45 .transfer_type = USB_TRANSFER_INTERRUPT,
46 .direction = USB_DIRECTION_IN,
47 .interface_class = USB_CLASS_HID,
48 .interface_subclass = USB_HID_SUBCLASS_BOOT,
49 .interface_protocol = USB_HID_PROTOCOL_MOUSE,
50 .flags = 0
51};
52
53/** Initialize poll pipe.
54 *
55 * Expects that session is already started on control pipe zero.
56 *
57 * @param mouse Mouse device.
58 * @param my_interface Interface number.
59 * @return Error code.
60 */
61static int intialize_poll_pipe(usb_mouse_t *mouse, int my_interface)
62{
63 assert(usb_endpoint_pipe_is_session_started(&mouse->ctrl_pipe));
64
65 int rc;
66
67 void *config_descriptor;
68 size_t config_descriptor_size;
69
70 rc = usb_request_get_full_configuration_descriptor_alloc(
71 &mouse->ctrl_pipe, 0, &config_descriptor, &config_descriptor_size);
72 if (rc != EOK) {
73 return rc;
74 }
75
76 usb_endpoint_mapping_t endpoint_mapping[1] = {
77 {
78 .pipe = &mouse->poll_pipe,
79 .description = &poll_endpoint_description,
80 .interface_no = my_interface
81 }
82 };
83
84 rc = usb_endpoint_pipe_initialize_from_configuration(endpoint_mapping,
85 1, config_descriptor, config_descriptor_size, &mouse->wire);
86 if (rc != EOK) {
87 return rc;
88 }
89
90 if (!endpoint_mapping[0].present) {
91 return ENOENT;
92 }
93
94 mouse->poll_interval_us = 1000 * endpoint_mapping[0].descriptor->poll_interval;
95
96 usb_log_debug("prepared polling endpoint %d (interval %zu).\n",
97 mouse->poll_pipe.endpoint_no, mouse->poll_interval_us);
98
99 return EOK;
100}
101
102static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
103static ddf_dev_ops_t mouse_ops = {
104 .default_handler = default_connection_handler
105};
106
107/** Default handler for IPC methods not handled by DDF.
108 *
109 * @param dev Device handling the call.
110 * @param icallid Call id.
111 * @param icall Call data.
112 */
113void default_connection_handler(ddf_fun_t *fun,
114 ipc_callid_t icallid, ipc_call_t *icall)
115{
116 sysarg_t method = IPC_GET_IMETHOD(*icall);
117
118 usb_mouse_t *mouse = (usb_mouse_t *) fun->driver_data;
119 assert(mouse != NULL);
120
121 if (method == IPC_M_CONNECT_TO_ME) {
122 int callback = IPC_GET_ARG5(*icall);
123
124 if (mouse->console_phone != -1) {
125 async_answer_0(icallid, ELIMIT);
126 return;
127 }
128
129 mouse->console_phone = callback;
130 async_answer_0(icallid, EOK);
131 return;
132 }
133
134 async_answer_0(icallid, EINVAL);
135}
136
137
138int usb_mouse_create(ddf_dev_t *dev)
139{
140 usb_mouse_t *mouse = malloc(sizeof(usb_mouse_t));
141 if (mouse == NULL) {
142 return ENOMEM;
143 }
144 mouse->device = dev;
145 mouse->console_phone = -1;
146
147 int rc;
148
149 /* Initialize the backing connection. */
150 rc = usb_device_connection_initialize_from_device(&mouse->wire, dev);
151 if (rc != EOK) {
152 goto leave;
153 }
154
155 /* Initialize the default control pipe. */
156 rc = usb_endpoint_pipe_initialize_default_control(&mouse->ctrl_pipe,
157 &mouse->wire);
158 if (rc != EOK) {
159 goto leave;
160 }
161
162 rc = usb_endpoint_pipe_start_session(&mouse->ctrl_pipe);
163 if (rc != EOK) {
164 goto leave;
165 }
166
167 rc = intialize_poll_pipe(mouse, usb_device_get_assigned_interface(dev));
168
169 /* We can ignore error here. */
170 usb_endpoint_pipe_end_session(&mouse->ctrl_pipe);
171
172 if (rc != EOK) {
173 goto leave;
174 }
175
176 /* Create DDF function. */
177 mouse->mouse_fun = ddf_fun_create(dev, fun_exposed, "mouse");
178 if (mouse->mouse_fun == NULL) {
179 rc = ENOMEM;
180 goto leave;
181 }
182
183 mouse->mouse_fun->ops = &mouse_ops;
184
185 rc = ddf_fun_bind(mouse->mouse_fun);
186 if (rc != EOK) {
187 goto leave;
188 }
189
190 /* Add the function to mouse class. */
191 rc = ddf_fun_add_to_class(mouse->mouse_fun, "mouse");
192 if (rc != EOK) {
193 goto leave;
194 }
195
196 /* Everything allright. */
197 dev->driver_data = mouse;
198 mouse->mouse_fun->driver_data = mouse;
199
200 return EOK;
201
202leave:
203 free(mouse);
204
205 return rc;
206}
207
208/**
209 * @}
210 */
Note: See TracBrowser for help on using the repository browser.