source: mainline/uspace/drv/usbkbd/main.c@ 8365533

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8365533 was 243cb86, checked in by Lubos Slovak <lubos.slovak@…>, 15 years ago

Merge from development + several changes to hid driver.

Changes to hid driver:

  • copied some code to usbkbd_get_descriptors() function
  • base structure for hid descriptor and report parser (files uspace/lib/usb/include/usb/classes/hidparser.h

and uspace/lib/usb/src/hidparser.c)

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/*
2 * Copyright (c) 2010 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#include <usb/usbdrv.h>
29#include <driver.h>
30#include <ipc/driver.h>
31#include <errno.h>
32#include <fibril.h>
33#include <usb/classes/hid.h>
34#include <usb/classes/hidparser.h>
35#include <usb/devreq.h>
36
37#define BUFFER_SIZE 32
38#define NAME "usbkbd"
39
40static const usb_endpoint_t CONTROL_EP = 0;
41
42/*
43 * Callbacks for parser
44 */
45static void usbkbd_process_keycodes(const uint16_t *key_codes, size_t count,
46 void *arg)
47{
48
49}
50
51/*
52 * Kbd functions
53 */
54static int usbkbd_get_descriptors()
55{
56 // copy-pasted:
57
58 /* Prepare the setup packet. */
59 usb_device_request_setup_packet_t setup_packet = {
60 .request_type = 128,
61 .request = USB_DEVREQ_GET_DESCRIPTOR,
62 .index = 0,
63 .length = sizeof(usb_standard_device_descriptor_t)
64 };
65
66 setup_packet.value_high = USB_DESCTYPE_DEVICE;
67 setup_packet.value_low = 0;
68
69 /* Prepare local descriptor. */
70 size_t actually_transferred = 0;
71 usb_standard_device_descriptor_t descriptor_tmp;
72
73 /* Perform the control read transaction. */
74 int rc = usb_drv_psync_control_read(phone, target,
75 &setup_packet, sizeof(setup_packet),
76 &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred);
77
78 if (rc != EOK) {
79 return rc;
80 }
81
82 // end of copy-paste
83}
84
85static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
86{
87 usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)malloc(
88 sizeof(usb_hid_dev_kbd_t));
89
90 if (kbd_dev == NULL) {
91 fprintf(stderr, NAME ": No memory!\n");
92 return NULL;
93 }
94
95 kbd_dev->device = dev;
96
97 // get phone to my HC and save it as my parent's phone
98 // TODO: maybe not a good idea if DDF will use parent_phone
99 kbd_dev->device->parent_phone = usb_drv_hc_connect(dev, 0);
100
101 kbd_dev->address = usb_drv_get_my_address(dev->parent_phone,
102 dev);
103
104 // doesn't matter now that we have no address
105// if (kbd_dev->address < 0) {
106// fprintf(stderr, NAME ": No device address!\n");
107// free(kbd_dev);
108// return NULL;
109// }
110
111 // default endpoint
112 kbd_dev->default_ep = CONTROL_EP;
113
114 // TODO: get descriptors
115 usbkbd_get_descriptors();
116 // TODO: parse descriptors and save endpoints
117
118 return kbd_dev;
119}
120
121static void usbkbd_process_interrupt_in(usb_hid_dev_kbd_t *kbd_dev,
122 uint8_t *buffer, size_t actual_size)
123{
124 /*
125 * here, the parser will be called, probably with some callbacks
126 * now only take last 6 bytes and process, i.e. send to kbd
127 */
128
129 usb_hid_report_in_callbacks_t *callbacks =
130 (usb_hid_report_in_callbacks_t *)malloc(
131 sizeof(usb_hid_report_in_callbacks_t));
132 callbacks->keyboard = usbkbd_process_keycodes;
133
134 usb_hid_parse_report(kbd_dev->parser, buffer, callbacks, NULL);
135}
136
137static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev)
138{
139 int rc;
140 usb_handle_t handle;
141 uint8_t buffer[BUFFER_SIZE];
142 size_t actual_size;
143 //usb_endpoint_t poll_endpoint = 1;
144
145// usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
146// dev);
147// if (my_address < 0) {
148// return;
149// }
150
151 usb_target_t poll_target = {
152 .address = kbd_dev->address,
153 .endpoint = kbd_dev->default_ep
154 };
155
156 while (true) {
157 rc = usb_drv_async_interrupt_in(kbd_dev->device->parent_phone,
158 poll_target, buffer, BUFFER_SIZE, &actual_size, &handle);
159
160 if (rc != EOK) {
161 continue;
162 }
163
164 rc = usb_drv_async_wait_for(handle);
165 if (rc != EOK) {
166 continue;
167 }
168
169 /*
170 * If the keyboard answered with NAK, it returned no data.
171 * This implies that no change happened since last query.
172 */
173 if (actual_size == 0) {
174 continue;
175 }
176
177 /*
178 * TODO: Process pressed keys.
179 */
180 usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size);
181 }
182
183 // not reached
184 assert(0);
185}
186
187static int usbkbd_fibril_device(void *arg)
188{
189 printf("!!! USB device fibril\n");
190
191 if (arg == NULL) {
192 printf("No device!\n");
193 return -1;
194 }
195
196 device_t *dev = (device_t *)arg;
197
198 // initialize device (get and process descriptors, get address, etc.)
199 usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev);
200
201 usbkbd_poll_keyboard(kbd_dev);
202
203 return EOK;
204}
205
206static int usbkbd_add_device(device_t *dev)
207{
208 /* For now, fail immediately. */
209 //return ENOTSUP;
210
211 /*
212 * When everything is okay, connect to "our" HC.
213 *
214 * Not supported yet, skip..
215 */
216// int phone = usb_drv_hc_connect(dev, 0);
217// if (phone < 0) {
218// /*
219// * Connecting to HC failed, roll-back and announce
220// * failure.
221// */
222// return phone;
223// }
224
225// dev->parent_phone = phone;
226
227 /*
228 * Create new fibril for handling this keyboard
229 */
230 fid_t fid = fibril_create(usbkbd_fibril_device, dev);
231 if (fid == 0) {
232 printf("%s: failed to start fibril for HID device\n", NAME);
233 return ENOMEM;
234 }
235 fibril_add_ready(fid);
236
237 /*
238 * Hurrah, device is initialized.
239 */
240 return EOK;
241}
242
243static driver_ops_t kbd_driver_ops = {
244 .add_device = usbkbd_add_device,
245};
246
247static driver_t kbd_driver = {
248 .name = NAME,
249 .driver_ops = &kbd_driver_ops
250};
251
252int main(int argc, char *argv[])
253{
254 return driver_main(&kbd_driver);
255}
Note: See TracBrowser for help on using the repository browser.