source: mainline/uspace/drv/usbhid/generic/hiddev.c@ 3facf63a

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

DFF function for generic HID subdriver.

  • Changed usbhid interface - sending only the raw buffer.
  • Implemented interface in generic HID subdriver.

Just a proof-of-concept, this implementation has many issues
(e.g. synchronization, reporting old events, etc.).

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2 * Copyright (c) 2011 Lubos Slovak
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 drvusbhid
30 * @{
31 */
32/**
33 * @file
34 * USB HID driver API.
35 */
36
37#include <usb/debug.h>
38#include <usb/classes/classes.h>
39#include <errno.h>
40#include <str_error.h>
41
42#include <usbhid_iface.h>
43
44#include "hiddev.h"
45#include "usbhid.h"
46
47/*----------------------------------------------------------------------------*/
48
49usb_endpoint_description_t usb_hid_generic_poll_endpoint_description = {
50 .transfer_type = USB_TRANSFER_INTERRUPT,
51 .direction = USB_DIRECTION_IN,
52 .interface_class = USB_CLASS_HID,
53 .flags = 0
54};
55
56const char *HID_GENERIC_FUN_NAME = "hid";
57const char *HID_GENERIC_CLASS_NAME = "hid";
58
59/*----------------------------------------------------------------------------*/
60
61static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun);
62
63static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer,
64 size_t size, size_t *act_size, unsigned int flags);
65
66/*----------------------------------------------------------------------------*/
67
68static usbhid_iface_t usb_generic_iface = {
69 .get_event = usb_generic_hid_get_event,
70 .get_event_length = usb_generic_hid_get_event_length
71};
72
73static ddf_dev_ops_t usb_generic_hid_ops = {
74 .interfaces[USBHID_DEV_IFACE] = &usb_generic_iface
75};
76
77/*----------------------------------------------------------------------------*/
78
79static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun)
80{
81 if (fun == NULL || fun->driver_data) {
82 return 0;
83 }
84
85 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
86
87 return hid_dev->input_report_size;
88}
89
90/*----------------------------------------------------------------------------*/
91
92static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer,
93 size_t size, size_t *act_size, unsigned int flags)
94{
95 if (fun == NULL || fun->driver_data) {
96 return EINVAL;
97 }
98
99 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
100
101 if (hid_dev->input_report_size > size) {
102 return EINVAL; // TODO: other error code
103 }
104
105 /*! @todo This should probably be atomic. */
106 memcpy(buffer, hid_dev->input_report, hid_dev->input_report_size);
107 *act_size = hid_dev->input_report_size;
108
109 // clear the buffer so that it will not be received twice
110 memset(hid_dev->input_report, 0, hid_dev->input_report_size);
111
112 return EOK;
113}
114
115/*----------------------------------------------------------------------------*/
116
117static int usb_generic_hid_create_function(usb_hid_dev_t *hid_dev)
118{
119 /* Create the function exposed under /dev/devices. */
120 /** @todo Generate numbers for the devices? */
121 usb_log_debug("Creating DDF function %s...\n", HID_GENERIC_FUN_NAME);
122 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
123 HID_GENERIC_FUN_NAME);
124 if (fun == NULL) {
125 usb_log_error("Could not create DDF function node.\n");
126 return ENOMEM;
127 }
128
129 int rc = ddf_fun_bind(fun);
130 if (rc != EOK) {
131 usb_log_error("Could not bind DDF function: %s.\n",
132 str_error(rc));
133 ddf_fun_destroy(fun);
134 return rc;
135 }
136
137 fun->ops = &usb_generic_hid_ops;
138 fun->driver_data = hid_dev;
139
140 return EOK;
141}
142
143/*----------------------------------------------------------------------------*/
144
145int usb_generic_hid_init(usb_hid_dev_t *hid_dev)
146{
147 if (hid_dev == NULL) {
148 return EINVAL;
149 }
150
151 return usb_generic_hid_create_function(hid_dev);
152}
153
154/*----------------------------------------------------------------------------*/
155
156bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev,
157 uint8_t *buffer, size_t buffer_size)
158{
159 usb_log_debug("usb_hid_polling_callback(%p, %p, %zu)\n",
160 hid_dev, buffer, buffer_size);
161 usb_debug_str_buffer(buffer, buffer_size, 0);
162 return true;
163}
164
165/**
166 * @}
167 */
Note: See TracBrowser for help on using the repository browser.