Lines Matching +full:ctrl +full:- +full:len
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * uvc_status.c -- USB Video Class driver - Status endpoint
5 * Copyright (C) 2005-2009
18 /* --------------------------------------------------------------------------
33 list_for_each_entry(stream, &dev->streams, list) { in uvc_input_has_button()
34 if (stream->header.bTriggerSupport == 1 && in uvc_input_has_button()
35 stream->header.bTriggerUsage == 1) in uvc_input_has_button()
52 return -ENOMEM; in uvc_input_init()
54 usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys)); in uvc_input_init()
55 strlcat(dev->input_phys, "/button", sizeof(dev->input_phys)); in uvc_input_init()
57 input->name = dev->name; in uvc_input_init()
58 input->phys = dev->input_phys; in uvc_input_init()
59 usb_to_input_id(dev->udev, &input->id); in uvc_input_init()
60 input->dev.parent = &dev->intf->dev; in uvc_input_init()
62 __set_bit(EV_KEY, input->evbit); in uvc_input_init()
63 __set_bit(KEY_CAMERA, input->keybit); in uvc_input_init()
68 dev->input = input; in uvc_input_init()
78 if (dev->input) in uvc_input_unregister()
79 input_unregister_device(dev->input); in uvc_input_unregister()
85 if (dev->input) { in uvc_input_report_key()
86 input_report_key(dev->input, code, value); in uvc_input_report_key()
87 input_sync(dev->input); in uvc_input_report_key()
97 /* --------------------------------------------------------------------------
101 struct uvc_status *status, int len) in uvc_event_streaming() argument
103 if (len <= offsetof(struct uvc_status, bEvent)) { in uvc_event_streaming()
109 if (status->bEvent == 0) { in uvc_event_streaming()
110 if (len <= offsetof(struct uvc_status, streaming)) in uvc_event_streaming()
113 uvc_dbg(dev, STATUS, "Button (intf %u) %s len %d\n", in uvc_event_streaming()
114 status->bOriginator, in uvc_event_streaming()
115 status->streaming.button ? "pressed" : "released", len); in uvc_event_streaming()
116 uvc_input_report_key(dev, KEY_CAMERA, status->streaming.button); in uvc_event_streaming()
118 uvc_dbg(dev, STATUS, "Stream %u error event %02x len %d\n", in uvc_event_streaming()
119 status->bOriginator, status->bEvent, len); in uvc_event_streaming()
132 struct uvc_control *ctrl; in uvc_event_entity_find_ctrl() local
135 for (i = 0, ctrl = entity->controls; i < entity->ncontrols; i++, ctrl++) in uvc_event_entity_find_ctrl()
136 if (ctrl->info.selector == selector) in uvc_event_entity_find_ctrl()
137 return ctrl; in uvc_event_entity_find_ctrl()
146 list_for_each_entry((*chain), &dev->chains, list) { in uvc_event_find_ctrl()
148 struct uvc_control *ctrl; in uvc_event_find_ctrl() local
150 list_for_each_entry(entity, &(*chain)->entities, chain) { in uvc_event_find_ctrl()
151 if (entity->id != status->bOriginator) in uvc_event_find_ctrl()
154 ctrl = uvc_event_entity_find_ctrl(entity, in uvc_event_find_ctrl()
155 status->control.bSelector); in uvc_event_find_ctrl()
156 if (ctrl) in uvc_event_find_ctrl()
157 return ctrl; in uvc_event_find_ctrl()
165 const struct uvc_status *status, int len) in uvc_event_control() argument
168 struct uvc_device *dev = urb->context; in uvc_event_control()
170 struct uvc_control *ctrl; in uvc_event_control() local
172 if (len < 6 || status->bEvent != 0 || in uvc_event_control()
173 status->control.bAttribute >= ARRAY_SIZE(attrs)) { in uvc_event_control()
178 uvc_dbg(dev, STATUS, "Control %u/%u %s change len %d\n", in uvc_event_control()
179 status->bOriginator, status->control.bSelector, in uvc_event_control()
180 attrs[status->control.bAttribute], len); in uvc_event_control()
183 ctrl = uvc_event_find_ctrl(dev, status, &chain); in uvc_event_control()
184 if (!ctrl) in uvc_event_control()
187 switch (status->control.bAttribute) { in uvc_event_control()
189 return uvc_ctrl_status_event_async(urb, chain, ctrl, in uvc_event_control()
190 status->control.bValue); in uvc_event_control()
204 struct uvc_device *dev = urb->context; in uvc_status_complete()
205 int len, ret; in uvc_status_complete() local
207 switch (urb->status) { in uvc_status_complete()
211 case -ENOENT: /* usb_kill_urb() called. */ in uvc_status_complete()
212 case -ECONNRESET: /* usb_unlink_urb() called. */ in uvc_status_complete()
213 case -ESHUTDOWN: /* The endpoint is being disabled. */ in uvc_status_complete()
214 case -EPROTO: /* Device is disconnected (reported by some host controllers). */ in uvc_status_complete()
218 dev_warn(&dev->udev->dev, in uvc_status_complete()
219 "Non-zero status (%d) in status completion handler.\n", in uvc_status_complete()
220 urb->status); in uvc_status_complete()
224 len = urb->actual_length; in uvc_status_complete()
225 if (len > 0) { in uvc_status_complete()
226 switch (dev->status->bStatusType & 0x0f) { in uvc_status_complete()
228 if (uvc_event_control(urb, dev->status, len)) in uvc_status_complete()
235 uvc_event_streaming(dev, dev->status, len); in uvc_status_complete()
241 dev->status->bStatusType); in uvc_status_complete()
247 urb->interval = dev->int_ep->desc.bInterval; in uvc_status_complete()
250 dev_err(&dev->udev->dev, in uvc_status_complete()
256 struct usb_host_endpoint *ep = dev->int_ep; in uvc_status_init()
265 dev->status = kzalloc(sizeof(*dev->status), GFP_KERNEL); in uvc_status_init()
266 if (!dev->status) in uvc_status_init()
267 return -ENOMEM; in uvc_status_init()
269 dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); in uvc_status_init()
270 if (!dev->int_urb) { in uvc_status_init()
271 kfree(dev->status); in uvc_status_init()
272 return -ENOMEM; in uvc_status_init()
275 pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress); in uvc_status_init()
278 * For high-speed interrupt endpoints, the bInterval value is used as in uvc_status_init()
281 interval = ep->desc.bInterval; in uvc_status_init()
282 if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH && in uvc_status_init()
283 (dev->quirks & UVC_QUIRK_STATUS_INTERVAL)) in uvc_status_init()
284 interval = fls(interval) - 1; in uvc_status_init()
286 usb_fill_int_urb(dev->int_urb, dev->udev, pipe, in uvc_status_init()
287 dev->status, sizeof(*dev->status), uvc_status_complete, in uvc_status_init()
295 usb_kill_urb(dev->int_urb); in uvc_status_unregister()
301 usb_free_urb(dev->int_urb); in uvc_status_cleanup()
302 kfree(dev->status); in uvc_status_cleanup()
307 if (dev->int_urb == NULL) in uvc_status_start()
310 return usb_submit_urb(dev->int_urb, flags); in uvc_status_start()
315 struct uvc_ctrl_work *w = &dev->async_ctrl; in uvc_status_stop()
323 smp_store_release(&dev->flush_status, true); in uvc_status_stop()
329 if (cancel_work_sync(&w->work)) in uvc_status_stop()
330 uvc_ctrl_status_event(w->chain, w->ctrl, w->data); in uvc_status_stop()
333 usb_kill_urb(dev->int_urb); in uvc_status_stop()
341 if (cancel_work_sync(&w->work)) in uvc_status_stop()
342 uvc_ctrl_status_event(w->chain, w->ctrl, w->data); in uvc_status_stop()
351 smp_store_release(&dev->flush_status, false); in uvc_status_stop()