xref: /openbmc/linux/drivers/media/usb/uvc/uvc_status.c (revision 3bc22dc66a4f386393119118169ed0b78c389898)
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 struct uvc_streaming_status {
100 	u8	bStatusType;
101 	u8	bOriginator;
102 	u8	bEvent;
103 	u8	bValue[];
104 } __packed;
105 
106 struct uvc_control_status {
107 	u8	bStatusType;
108 	u8	bOriginator;
109 	u8	bEvent;
110 	u8	bSelector;
111 	u8	bAttribute;
112 	u8	bValue[];
113 } __packed;
114 
115 static void uvc_event_streaming(struct uvc_device *dev,
116 				struct uvc_streaming_status *status, int len)
117 {
118 	if (len < 3) {
119 		uvc_dbg(dev, STATUS,
120 			"Invalid streaming status event received\n");
121 		return;
122 	}
123 
124 	if (status->bEvent == 0) {
125 		if (len < 4)
126 			return;
127 		uvc_dbg(dev, STATUS, "Button (intf %u) %s len %d\n",
128 			status->bOriginator,
129 			status->bValue[0] ? "pressed" : "released", len);
130 		uvc_input_report_key(dev, KEY_CAMERA, status->bValue[0]);
131 	} else {
132 		uvc_dbg(dev, STATUS, "Stream %u error event %02x len %d\n",
133 			status->bOriginator, status->bEvent, len);
134 	}
135 }
136 
137 #define UVC_CTRL_VALUE_CHANGE	0
138 #define UVC_CTRL_INFO_CHANGE	1
139 #define UVC_CTRL_FAILURE_CHANGE	2
140 #define UVC_CTRL_MIN_CHANGE	3
141 #define UVC_CTRL_MAX_CHANGE	4
142 
143 static struct uvc_control *uvc_event_entity_find_ctrl(struct uvc_entity *entity,
144 						      u8 selector)
145 {
146 	struct uvc_control *ctrl;
147 	unsigned int i;
148 
149 	for (i = 0, ctrl = entity->controls; i < entity->ncontrols; i++, ctrl++)
150 		if (ctrl->info.selector == selector)
151 			return ctrl;
152 
153 	return NULL;
154 }
155 
156 static struct uvc_control *uvc_event_find_ctrl(struct uvc_device *dev,
157 					const struct uvc_control_status *status,
158 					struct uvc_video_chain **chain)
159 {
160 	list_for_each_entry((*chain), &dev->chains, list) {
161 		struct uvc_entity *entity;
162 		struct uvc_control *ctrl;
163 
164 		list_for_each_entry(entity, &(*chain)->entities, chain) {
165 			if (entity->id != status->bOriginator)
166 				continue;
167 
168 			ctrl = uvc_event_entity_find_ctrl(entity,
169 							  status->bSelector);
170 			if (ctrl)
171 				return ctrl;
172 		}
173 	}
174 
175 	return NULL;
176 }
177 
178 static bool uvc_event_control(struct urb *urb,
179 			      const struct uvc_control_status *status, int len)
180 {
181 	static const char *attrs[] = { "value", "info", "failure", "min", "max" };
182 	struct uvc_device *dev = urb->context;
183 	struct uvc_video_chain *chain;
184 	struct uvc_control *ctrl;
185 
186 	if (len < 6 || status->bEvent != 0 ||
187 	    status->bAttribute >= ARRAY_SIZE(attrs)) {
188 		uvc_dbg(dev, STATUS, "Invalid control status event received\n");
189 		return false;
190 	}
191 
192 	uvc_dbg(dev, STATUS, "Control %u/%u %s change len %d\n",
193 		status->bOriginator, status->bSelector,
194 		attrs[status->bAttribute], len);
195 
196 	/* Find the control. */
197 	ctrl = uvc_event_find_ctrl(dev, status, &chain);
198 	if (!ctrl)
199 		return false;
200 
201 	switch (status->bAttribute) {
202 	case UVC_CTRL_VALUE_CHANGE:
203 		return uvc_ctrl_status_event_async(urb, chain, ctrl,
204 						   status->bValue);
205 
206 	case UVC_CTRL_INFO_CHANGE:
207 	case UVC_CTRL_FAILURE_CHANGE:
208 	case UVC_CTRL_MIN_CHANGE:
209 	case UVC_CTRL_MAX_CHANGE:
210 		break;
211 	}
212 
213 	return false;
214 }
215 
216 static void uvc_status_complete(struct urb *urb)
217 {
218 	struct uvc_device *dev = urb->context;
219 	int len, ret;
220 
221 	switch (urb->status) {
222 	case 0:
223 		break;
224 
225 	case -ENOENT:		/* usb_kill_urb() called. */
226 	case -ECONNRESET:	/* usb_unlink_urb() called. */
227 	case -ESHUTDOWN:	/* The endpoint is being disabled. */
228 	case -EPROTO:		/* Device is disconnected (reported by some host controllers). */
229 		return;
230 
231 	default:
232 		dev_warn(&dev->udev->dev,
233 			 "Non-zero status (%d) in status completion handler.\n",
234 			 urb->status);
235 		return;
236 	}
237 
238 	len = urb->actual_length;
239 	if (len > 0) {
240 		switch (dev->status[0] & 0x0f) {
241 		case UVC_STATUS_TYPE_CONTROL: {
242 			struct uvc_control_status *status =
243 				(struct uvc_control_status *)dev->status;
244 
245 			if (uvc_event_control(urb, status, len))
246 				/* The URB will be resubmitted in work context. */
247 				return;
248 			break;
249 		}
250 
251 		case UVC_STATUS_TYPE_STREAMING: {
252 			struct uvc_streaming_status *status =
253 				(struct uvc_streaming_status *)dev->status;
254 
255 			uvc_event_streaming(dev, status, len);
256 			break;
257 		}
258 
259 		default:
260 			uvc_dbg(dev, STATUS, "Unknown status event type %u\n",
261 				dev->status[0]);
262 			break;
263 		}
264 	}
265 
266 	/* Resubmit the URB. */
267 	urb->interval = dev->int_ep->desc.bInterval;
268 	ret = usb_submit_urb(urb, GFP_ATOMIC);
269 	if (ret < 0)
270 		dev_err(&dev->udev->dev,
271 			"Failed to resubmit status URB (%d).\n", ret);
272 }
273 
274 int uvc_status_init(struct uvc_device *dev)
275 {
276 	struct usb_host_endpoint *ep = dev->int_ep;
277 	unsigned int pipe;
278 	int interval;
279 
280 	if (ep == NULL)
281 		return 0;
282 
283 	uvc_input_init(dev);
284 
285 	dev->status = kzalloc(UVC_MAX_STATUS_SIZE, GFP_KERNEL);
286 	if (dev->status == NULL)
287 		return -ENOMEM;
288 
289 	dev->int_urb = usb_alloc_urb(0, GFP_KERNEL);
290 	if (dev->int_urb == NULL) {
291 		kfree(dev->status);
292 		return -ENOMEM;
293 	}
294 
295 	pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
296 
297 	/*
298 	 * For high-speed interrupt endpoints, the bInterval value is used as
299 	 * an exponent of two. Some developers forgot about it.
300 	 */
301 	interval = ep->desc.bInterval;
302 	if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH &&
303 	    (dev->quirks & UVC_QUIRK_STATUS_INTERVAL))
304 		interval = fls(interval) - 1;
305 
306 	usb_fill_int_urb(dev->int_urb, dev->udev, pipe,
307 		dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete,
308 		dev, interval);
309 
310 	return 0;
311 }
312 
313 void uvc_status_unregister(struct uvc_device *dev)
314 {
315 	usb_kill_urb(dev->int_urb);
316 	uvc_input_unregister(dev);
317 }
318 
319 void uvc_status_cleanup(struct uvc_device *dev)
320 {
321 	usb_free_urb(dev->int_urb);
322 	kfree(dev->status);
323 }
324 
325 int uvc_status_start(struct uvc_device *dev, gfp_t flags)
326 {
327 	if (dev->int_urb == NULL)
328 		return 0;
329 
330 	return usb_submit_urb(dev->int_urb, flags);
331 }
332 
333 void uvc_status_stop(struct uvc_device *dev)
334 {
335 	usb_kill_urb(dev->int_urb);
336 }
337