xref: /openbmc/linux/drivers/media/usb/uvc/uvc_status.c (revision adfd3910c27fbc0959ae5f1dafaec563f7d0bdd2)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *      uvc_status.c  --  USB Video Class driver - Status endpoint
4  *
5  *      Copyright (C) 2005-2009
6  *          Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7  */
8 
9 #include <linux/kernel.h>
10 #include <linux/input.h>
11 #include <linux/slab.h>
12 #include <linux/usb.h>
13 #include <linux/usb/input.h>
14 
15 #include "uvcvideo.h"
16 
17 /* --------------------------------------------------------------------------
18  * Input device
19  */
20 #ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
21 
22 static bool uvc_input_has_button(struct uvc_device *dev)
23 {
24 	struct uvc_streaming *stream;
25 
26 	/*
27 	 * The device has button events if both bTriggerSupport and
28 	 * bTriggerUsage are one. Otherwise the camera button does not
29 	 * exist or is handled automatically by the camera without host
30 	 * driver or client application intervention.
31 	 */
32 	list_for_each_entry(stream, &dev->streams, list) {
33 		if (stream->header.bTriggerSupport == 1 &&
34 		    stream->header.bTriggerUsage == 1)
35 			return true;
36 	}
37 
38 	return false;
39 }
40 
41 static int uvc_input_init(struct uvc_device *dev)
42 {
43 	struct input_dev *input;
44 	int ret;
45 
46 	if (!uvc_input_has_button(dev))
47 		return 0;
48 
49 	input = input_allocate_device();
50 	if (input == NULL)
51 		return -ENOMEM;
52 
53 	usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys));
54 	strlcat(dev->input_phys, "/button", sizeof(dev->input_phys));
55 
56 	input->name = dev->name;
57 	input->phys = dev->input_phys;
58 	usb_to_input_id(dev->udev, &input->id);
59 	input->dev.parent = &dev->intf->dev;
60 
61 	__set_bit(EV_KEY, input->evbit);
62 	__set_bit(KEY_CAMERA, input->keybit);
63 
64 	if ((ret = input_register_device(input)) < 0)
65 		goto error;
66 
67 	dev->input = input;
68 	return 0;
69 
70 error:
71 	input_free_device(input);
72 	return ret;
73 }
74 
75 static void uvc_input_unregister(struct uvc_device *dev)
76 {
77 	if (dev->input)
78 		input_unregister_device(dev->input);
79 }
80 
81 static void uvc_input_report_key(struct uvc_device *dev, unsigned int code,
82 	int value)
83 {
84 	if (dev->input) {
85 		input_report_key(dev->input, code, value);
86 		input_sync(dev->input);
87 	}
88 }
89 
90 #else
91 #define uvc_input_init(dev)
92 #define uvc_input_unregister(dev)
93 #define uvc_input_report_key(dev, code, value)
94 #endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */
95 
96 /* --------------------------------------------------------------------------
97  * Status interrupt endpoint
98  */
99 static void uvc_event_streaming(struct uvc_device *dev,
100 				struct uvc_status *status, int len)
101 {
102 	if (len <= offsetof(struct uvc_status, bEvent)) {
103 		uvc_dbg(dev, STATUS,
104 			"Invalid streaming status event received\n");
105 		return;
106 	}
107 
108 	if (status->bEvent == 0) {
109 		if (len <= offsetof(struct uvc_status, streaming))
110 			return;
111 
112 		uvc_dbg(dev, STATUS, "Button (intf %u) %s len %d\n",
113 			status->bOriginator,
114 			status->streaming.button ? "pressed" : "released", len);
115 		uvc_input_report_key(dev, KEY_CAMERA, status->streaming.button);
116 	} else {
117 		uvc_dbg(dev, STATUS, "Stream %u error event %02x len %d\n",
118 			status->bOriginator, status->bEvent, len);
119 	}
120 }
121 
122 #define UVC_CTRL_VALUE_CHANGE	0
123 #define UVC_CTRL_INFO_CHANGE	1
124 #define UVC_CTRL_FAILURE_CHANGE	2
125 #define UVC_CTRL_MIN_CHANGE	3
126 #define UVC_CTRL_MAX_CHANGE	4
127 
128 static struct uvc_control *uvc_event_entity_find_ctrl(struct uvc_entity *entity,
129 						      u8 selector)
130 {
131 	struct uvc_control *ctrl;
132 	unsigned int i;
133 
134 	for (i = 0, ctrl = entity->controls; i < entity->ncontrols; i++, ctrl++)
135 		if (ctrl->info.selector == selector)
136 			return ctrl;
137 
138 	return NULL;
139 }
140 
141 static struct uvc_control *uvc_event_find_ctrl(struct uvc_device *dev,
142 					const struct uvc_status *status,
143 					struct uvc_video_chain **chain)
144 {
145 	list_for_each_entry((*chain), &dev->chains, list) {
146 		struct uvc_entity *entity;
147 		struct uvc_control *ctrl;
148 
149 		list_for_each_entry(entity, &(*chain)->entities, chain) {
150 			if (entity->id != status->bOriginator)
151 				continue;
152 
153 			ctrl = uvc_event_entity_find_ctrl(entity,
154 						     status->control.bSelector);
155 			if (ctrl)
156 				return ctrl;
157 		}
158 	}
159 
160 	return NULL;
161 }
162 
163 static bool uvc_event_control(struct urb *urb,
164 			      const struct uvc_status *status, int len)
165 {
166 	static const char *attrs[] = { "value", "info", "failure", "min", "max" };
167 	struct uvc_device *dev = urb->context;
168 	struct uvc_video_chain *chain;
169 	struct uvc_control *ctrl;
170 
171 	if (len < 6 || status->bEvent != 0 ||
172 	    status->control.bAttribute >= ARRAY_SIZE(attrs)) {
173 		uvc_dbg(dev, STATUS, "Invalid control status event received\n");
174 		return false;
175 	}
176 
177 	uvc_dbg(dev, STATUS, "Control %u/%u %s change len %d\n",
178 		status->bOriginator, status->control.bSelector,
179 		attrs[status->control.bAttribute], len);
180 
181 	/* Find the control. */
182 	ctrl = uvc_event_find_ctrl(dev, status, &chain);
183 	if (!ctrl)
184 		return false;
185 
186 	switch (status->control.bAttribute) {
187 	case UVC_CTRL_VALUE_CHANGE:
188 		return uvc_ctrl_status_event_async(urb, chain, ctrl,
189 						   status->control.bValue);
190 
191 	case UVC_CTRL_INFO_CHANGE:
192 	case UVC_CTRL_FAILURE_CHANGE:
193 	case UVC_CTRL_MIN_CHANGE:
194 	case UVC_CTRL_MAX_CHANGE:
195 		break;
196 	}
197 
198 	return false;
199 }
200 
201 static void uvc_status_complete(struct urb *urb)
202 {
203 	struct uvc_device *dev = urb->context;
204 	int len, ret;
205 
206 	switch (urb->status) {
207 	case 0:
208 		break;
209 
210 	case -ENOENT:		/* usb_kill_urb() called. */
211 	case -ECONNRESET:	/* usb_unlink_urb() called. */
212 	case -ESHUTDOWN:	/* The endpoint is being disabled. */
213 	case -EPROTO:		/* Device is disconnected (reported by some host controllers). */
214 		return;
215 
216 	default:
217 		dev_warn(&dev->udev->dev,
218 			 "Non-zero status (%d) in status completion handler.\n",
219 			 urb->status);
220 		return;
221 	}
222 
223 	len = urb->actual_length;
224 	if (len > 0) {
225 		switch (dev->status->bStatusType & 0x0f) {
226 		case UVC_STATUS_TYPE_CONTROL: {
227 			if (uvc_event_control(urb, dev->status, len))
228 				/* The URB will be resubmitted in work context. */
229 				return;
230 			break;
231 		}
232 
233 		case UVC_STATUS_TYPE_STREAMING: {
234 			uvc_event_streaming(dev, dev->status, len);
235 			break;
236 		}
237 
238 		default:
239 			uvc_dbg(dev, STATUS, "Unknown status event type %u\n",
240 				dev->status->bStatusType);
241 			break;
242 		}
243 	}
244 
245 	/* Resubmit the URB. */
246 	urb->interval = dev->int_ep->desc.bInterval;
247 	ret = usb_submit_urb(urb, GFP_ATOMIC);
248 	if (ret < 0)
249 		dev_err(&dev->udev->dev,
250 			"Failed to resubmit status URB (%d).\n", ret);
251 }
252 
253 int uvc_status_init(struct uvc_device *dev)
254 {
255 	struct usb_host_endpoint *ep = dev->int_ep;
256 	unsigned int pipe;
257 	int interval;
258 
259 	if (ep == NULL)
260 		return 0;
261 
262 	uvc_input_init(dev);
263 
264 	dev->status = kzalloc(sizeof(*dev->status), GFP_KERNEL);
265 	if (!dev->status)
266 		return -ENOMEM;
267 
268 	dev->int_urb = usb_alloc_urb(0, GFP_KERNEL);
269 	if (!dev->int_urb) {
270 		kfree(dev->status);
271 		return -ENOMEM;
272 	}
273 
274 	pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
275 
276 	/*
277 	 * For high-speed interrupt endpoints, the bInterval value is used as
278 	 * an exponent of two. Some developers forgot about it.
279 	 */
280 	interval = ep->desc.bInterval;
281 	if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH &&
282 	    (dev->quirks & UVC_QUIRK_STATUS_INTERVAL))
283 		interval = fls(interval) - 1;
284 
285 	usb_fill_int_urb(dev->int_urb, dev->udev, pipe,
286 		dev->status, sizeof(*dev->status), uvc_status_complete,
287 		dev, interval);
288 
289 	return 0;
290 }
291 
292 void uvc_status_unregister(struct uvc_device *dev)
293 {
294 	usb_kill_urb(dev->int_urb);
295 	uvc_input_unregister(dev);
296 }
297 
298 void uvc_status_cleanup(struct uvc_device *dev)
299 {
300 	usb_free_urb(dev->int_urb);
301 	kfree(dev->status);
302 }
303 
304 int uvc_status_start(struct uvc_device *dev, gfp_t flags)
305 {
306 	if (dev->int_urb == NULL)
307 		return 0;
308 
309 	return usb_submit_urb(dev->int_urb, flags);
310 }
311 
312 void uvc_status_stop(struct uvc_device *dev)
313 {
314 	usb_kill_urb(dev->int_urb);
315 }
316