cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

webcam.c (13537B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 *	webcam.c -- USB webcam gadget driver
      4 *
      5 *	Copyright (C) 2009-2010
      6 *	    Laurent Pinchart (laurent.pinchart@ideasonboard.com)
      7 */
      8
      9#include <linux/kernel.h>
     10#include <linux/device.h>
     11#include <linux/module.h>
     12#include <linux/usb/video.h>
     13
     14#include "u_uvc.h"
     15
     16USB_GADGET_COMPOSITE_OPTIONS();
     17
     18/*-------------------------------------------------------------------------*/
     19
     20/* module parameters specific to the Video streaming endpoint */
     21static unsigned int streaming_interval = 1;
     22module_param(streaming_interval, uint, S_IRUGO|S_IWUSR);
     23MODULE_PARM_DESC(streaming_interval, "1 - 16");
     24
     25static unsigned int streaming_maxpacket = 1024;
     26module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR);
     27MODULE_PARM_DESC(streaming_maxpacket, "1 - 1023 (FS), 1 - 3072 (hs/ss)");
     28
     29static unsigned int streaming_maxburst;
     30module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR);
     31MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)");
     32
     33/* --------------------------------------------------------------------------
     34 * Device descriptor
     35 */
     36
     37#define WEBCAM_VENDOR_ID		0x1d6b	/* Linux Foundation */
     38#define WEBCAM_PRODUCT_ID		0x0102	/* Webcam A/V gadget */
     39#define WEBCAM_DEVICE_BCD		0x0010	/* 0.10 */
     40
     41static char webcam_vendor_label[] = "Linux Foundation";
     42static char webcam_product_label[] = "Webcam gadget";
     43static char webcam_config_label[] = "Video";
     44
     45/* string IDs are assigned dynamically */
     46
     47#define STRING_DESCRIPTION_IDX		USB_GADGET_FIRST_AVAIL_IDX
     48
     49static struct usb_string webcam_strings[] = {
     50	[USB_GADGET_MANUFACTURER_IDX].s = webcam_vendor_label,
     51	[USB_GADGET_PRODUCT_IDX].s = webcam_product_label,
     52	[USB_GADGET_SERIAL_IDX].s = "",
     53	[STRING_DESCRIPTION_IDX].s = webcam_config_label,
     54	{  }
     55};
     56
     57static struct usb_gadget_strings webcam_stringtab = {
     58	.language = 0x0409,	/* en-us */
     59	.strings = webcam_strings,
     60};
     61
     62static struct usb_gadget_strings *webcam_device_strings[] = {
     63	&webcam_stringtab,
     64	NULL,
     65};
     66
     67static struct usb_function_instance *fi_uvc;
     68static struct usb_function *f_uvc;
     69
     70static struct usb_device_descriptor webcam_device_descriptor = {
     71	.bLength		= USB_DT_DEVICE_SIZE,
     72	.bDescriptorType	= USB_DT_DEVICE,
     73	/* .bcdUSB = DYNAMIC */
     74	.bDeviceClass		= USB_CLASS_MISC,
     75	.bDeviceSubClass	= 0x02,
     76	.bDeviceProtocol	= 0x01,
     77	.bMaxPacketSize0	= 0, /* dynamic */
     78	.idVendor		= cpu_to_le16(WEBCAM_VENDOR_ID),
     79	.idProduct		= cpu_to_le16(WEBCAM_PRODUCT_ID),
     80	.bcdDevice		= cpu_to_le16(WEBCAM_DEVICE_BCD),
     81	.iManufacturer		= 0, /* dynamic */
     82	.iProduct		= 0, /* dynamic */
     83	.iSerialNumber		= 0, /* dynamic */
     84	.bNumConfigurations	= 0, /* dynamic */
     85};
     86
     87DECLARE_UVC_HEADER_DESCRIPTOR(1);
     88
     89static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = {
     90	.bLength		= UVC_DT_HEADER_SIZE(1),
     91	.bDescriptorType	= USB_DT_CS_INTERFACE,
     92	.bDescriptorSubType	= UVC_VC_HEADER,
     93	.bcdUVC			= cpu_to_le16(0x0110),
     94	.wTotalLength		= 0, /* dynamic */
     95	.dwClockFrequency	= cpu_to_le32(48000000),
     96	.bInCollection		= 0, /* dynamic */
     97	.baInterfaceNr[0]	= 0, /* dynamic */
     98};
     99
    100static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = {
    101	.bLength		= UVC_DT_CAMERA_TERMINAL_SIZE(3),
    102	.bDescriptorType	= USB_DT_CS_INTERFACE,
    103	.bDescriptorSubType	= UVC_VC_INPUT_TERMINAL,
    104	.bTerminalID		= 1,
    105	.wTerminalType		= cpu_to_le16(0x0201),
    106	.bAssocTerminal		= 0,
    107	.iTerminal		= 0,
    108	.wObjectiveFocalLengthMin	= cpu_to_le16(0),
    109	.wObjectiveFocalLengthMax	= cpu_to_le16(0),
    110	.wOcularFocalLength		= cpu_to_le16(0),
    111	.bControlSize		= 3,
    112	.bmControls[0]		= 2,
    113	.bmControls[1]		= 0,
    114	.bmControls[2]		= 0,
    115};
    116
    117static const struct uvc_processing_unit_descriptor uvc_processing = {
    118	.bLength		= UVC_DT_PROCESSING_UNIT_SIZE(2),
    119	.bDescriptorType	= USB_DT_CS_INTERFACE,
    120	.bDescriptorSubType	= UVC_VC_PROCESSING_UNIT,
    121	.bUnitID		= 2,
    122	.bSourceID		= 1,
    123	.wMaxMultiplier		= cpu_to_le16(16*1024),
    124	.bControlSize		= 2,
    125	.bmControls[0]		= 1,
    126	.bmControls[1]		= 0,
    127	.iProcessing		= 0,
    128	.bmVideoStandards	= 0,
    129};
    130
    131static const struct uvc_output_terminal_descriptor uvc_output_terminal = {
    132	.bLength		= UVC_DT_OUTPUT_TERMINAL_SIZE,
    133	.bDescriptorType	= USB_DT_CS_INTERFACE,
    134	.bDescriptorSubType	= UVC_VC_OUTPUT_TERMINAL,
    135	.bTerminalID		= 3,
    136	.wTerminalType		= cpu_to_le16(0x0101),
    137	.bAssocTerminal		= 0,
    138	.bSourceID		= 2,
    139	.iTerminal		= 0,
    140};
    141
    142DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 2);
    143
    144static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = {
    145	.bLength		= UVC_DT_INPUT_HEADER_SIZE(1, 2),
    146	.bDescriptorType	= USB_DT_CS_INTERFACE,
    147	.bDescriptorSubType	= UVC_VS_INPUT_HEADER,
    148	.bNumFormats		= 2,
    149	.wTotalLength		= 0, /* dynamic */
    150	.bEndpointAddress	= 0, /* dynamic */
    151	.bmInfo			= 0,
    152	.bTerminalLink		= 3,
    153	.bStillCaptureMethod	= 0,
    154	.bTriggerSupport	= 0,
    155	.bTriggerUsage		= 0,
    156	.bControlSize		= 1,
    157	.bmaControls[0][0]	= 0,
    158	.bmaControls[1][0]	= 4,
    159};
    160
    161static const struct uvc_format_uncompressed uvc_format_yuv = {
    162	.bLength		= UVC_DT_FORMAT_UNCOMPRESSED_SIZE,
    163	.bDescriptorType	= USB_DT_CS_INTERFACE,
    164	.bDescriptorSubType	= UVC_VS_FORMAT_UNCOMPRESSED,
    165	.bFormatIndex		= 1,
    166	.bNumFrameDescriptors	= 2,
    167	.guidFormat		=
    168		{ 'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00,
    169		 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71},
    170	.bBitsPerPixel		= 16,
    171	.bDefaultFrameIndex	= 1,
    172	.bAspectRatioX		= 0,
    173	.bAspectRatioY		= 0,
    174	.bmInterfaceFlags	= 0,
    175	.bCopyProtect		= 0,
    176};
    177
    178DECLARE_UVC_FRAME_UNCOMPRESSED(1);
    179DECLARE_UVC_FRAME_UNCOMPRESSED(3);
    180
    181static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = {
    182	.bLength		= UVC_DT_FRAME_UNCOMPRESSED_SIZE(3),
    183	.bDescriptorType	= USB_DT_CS_INTERFACE,
    184	.bDescriptorSubType	= UVC_VS_FRAME_UNCOMPRESSED,
    185	.bFrameIndex		= 1,
    186	.bmCapabilities		= 0,
    187	.wWidth			= cpu_to_le16(640),
    188	.wHeight		= cpu_to_le16(360),
    189	.dwMinBitRate		= cpu_to_le32(18432000),
    190	.dwMaxBitRate		= cpu_to_le32(55296000),
    191	.dwMaxVideoFrameBufferSize	= cpu_to_le32(460800),
    192	.dwDefaultFrameInterval	= cpu_to_le32(666666),
    193	.bFrameIntervalType	= 3,
    194	.dwFrameInterval[0]	= cpu_to_le32(666666),
    195	.dwFrameInterval[1]	= cpu_to_le32(1000000),
    196	.dwFrameInterval[2]	= cpu_to_le32(5000000),
    197};
    198
    199static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = {
    200	.bLength		= UVC_DT_FRAME_UNCOMPRESSED_SIZE(1),
    201	.bDescriptorType	= USB_DT_CS_INTERFACE,
    202	.bDescriptorSubType	= UVC_VS_FRAME_UNCOMPRESSED,
    203	.bFrameIndex		= 2,
    204	.bmCapabilities		= 0,
    205	.wWidth			= cpu_to_le16(1280),
    206	.wHeight		= cpu_to_le16(720),
    207	.dwMinBitRate		= cpu_to_le32(29491200),
    208	.dwMaxBitRate		= cpu_to_le32(29491200),
    209	.dwMaxVideoFrameBufferSize	= cpu_to_le32(1843200),
    210	.dwDefaultFrameInterval	= cpu_to_le32(5000000),
    211	.bFrameIntervalType	= 1,
    212	.dwFrameInterval[0]	= cpu_to_le32(5000000),
    213};
    214
    215static const struct uvc_format_mjpeg uvc_format_mjpg = {
    216	.bLength		= UVC_DT_FORMAT_MJPEG_SIZE,
    217	.bDescriptorType	= USB_DT_CS_INTERFACE,
    218	.bDescriptorSubType	= UVC_VS_FORMAT_MJPEG,
    219	.bFormatIndex		= 2,
    220	.bNumFrameDescriptors	= 2,
    221	.bmFlags		= 0,
    222	.bDefaultFrameIndex	= 1,
    223	.bAspectRatioX		= 0,
    224	.bAspectRatioY		= 0,
    225	.bmInterfaceFlags	= 0,
    226	.bCopyProtect		= 0,
    227};
    228
    229DECLARE_UVC_FRAME_MJPEG(1);
    230DECLARE_UVC_FRAME_MJPEG(3);
    231
    232static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = {
    233	.bLength		= UVC_DT_FRAME_MJPEG_SIZE(3),
    234	.bDescriptorType	= USB_DT_CS_INTERFACE,
    235	.bDescriptorSubType	= UVC_VS_FRAME_MJPEG,
    236	.bFrameIndex		= 1,
    237	.bmCapabilities		= 0,
    238	.wWidth			= cpu_to_le16(640),
    239	.wHeight		= cpu_to_le16(360),
    240	.dwMinBitRate		= cpu_to_le32(18432000),
    241	.dwMaxBitRate		= cpu_to_le32(55296000),
    242	.dwMaxVideoFrameBufferSize	= cpu_to_le32(460800),
    243	.dwDefaultFrameInterval	= cpu_to_le32(666666),
    244	.bFrameIntervalType	= 3,
    245	.dwFrameInterval[0]	= cpu_to_le32(666666),
    246	.dwFrameInterval[1]	= cpu_to_le32(1000000),
    247	.dwFrameInterval[2]	= cpu_to_le32(5000000),
    248};
    249
    250static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = {
    251	.bLength		= UVC_DT_FRAME_MJPEG_SIZE(1),
    252	.bDescriptorType	= USB_DT_CS_INTERFACE,
    253	.bDescriptorSubType	= UVC_VS_FRAME_MJPEG,
    254	.bFrameIndex		= 2,
    255	.bmCapabilities		= 0,
    256	.wWidth			= cpu_to_le16(1280),
    257	.wHeight		= cpu_to_le16(720),
    258	.dwMinBitRate		= cpu_to_le32(29491200),
    259	.dwMaxBitRate		= cpu_to_le32(29491200),
    260	.dwMaxVideoFrameBufferSize	= cpu_to_le32(1843200),
    261	.dwDefaultFrameInterval	= cpu_to_le32(5000000),
    262	.bFrameIntervalType	= 1,
    263	.dwFrameInterval[0]	= cpu_to_le32(5000000),
    264};
    265
    266static const struct uvc_color_matching_descriptor uvc_color_matching = {
    267	.bLength		= UVC_DT_COLOR_MATCHING_SIZE,
    268	.bDescriptorType	= USB_DT_CS_INTERFACE,
    269	.bDescriptorSubType	= UVC_VS_COLORFORMAT,
    270	.bColorPrimaries	= 1,
    271	.bTransferCharacteristics	= 1,
    272	.bMatrixCoefficients	= 4,
    273};
    274
    275static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = {
    276	(const struct uvc_descriptor_header *) &uvc_control_header,
    277	(const struct uvc_descriptor_header *) &uvc_camera_terminal,
    278	(const struct uvc_descriptor_header *) &uvc_processing,
    279	(const struct uvc_descriptor_header *) &uvc_output_terminal,
    280	NULL,
    281};
    282
    283static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = {
    284	(const struct uvc_descriptor_header *) &uvc_control_header,
    285	(const struct uvc_descriptor_header *) &uvc_camera_terminal,
    286	(const struct uvc_descriptor_header *) &uvc_processing,
    287	(const struct uvc_descriptor_header *) &uvc_output_terminal,
    288	NULL,
    289};
    290
    291static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = {
    292	(const struct uvc_descriptor_header *) &uvc_input_header,
    293	(const struct uvc_descriptor_header *) &uvc_format_yuv,
    294	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
    295	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
    296	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
    297	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
    298	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
    299	(const struct uvc_descriptor_header *) &uvc_color_matching,
    300	NULL,
    301};
    302
    303static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
    304	(const struct uvc_descriptor_header *) &uvc_input_header,
    305	(const struct uvc_descriptor_header *) &uvc_format_yuv,
    306	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
    307	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
    308	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
    309	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
    310	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
    311	(const struct uvc_descriptor_header *) &uvc_color_matching,
    312	NULL,
    313};
    314
    315static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = {
    316	(const struct uvc_descriptor_header *) &uvc_input_header,
    317	(const struct uvc_descriptor_header *) &uvc_format_yuv,
    318	(const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
    319	(const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
    320	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
    321	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
    322	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
    323	(const struct uvc_descriptor_header *) &uvc_color_matching,
    324	NULL,
    325};
    326
    327/* --------------------------------------------------------------------------
    328 * USB configuration
    329 */
    330
    331static int
    332webcam_config_bind(struct usb_configuration *c)
    333{
    334	int status = 0;
    335
    336	f_uvc = usb_get_function(fi_uvc);
    337	if (IS_ERR(f_uvc))
    338		return PTR_ERR(f_uvc);
    339
    340	status = usb_add_function(c, f_uvc);
    341	if (status < 0)
    342		usb_put_function(f_uvc);
    343
    344	return status;
    345}
    346
    347static struct usb_configuration webcam_config_driver = {
    348	.label			= webcam_config_label,
    349	.bConfigurationValue	= 1,
    350	.iConfiguration		= 0, /* dynamic */
    351	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
    352	.MaxPower		= CONFIG_USB_GADGET_VBUS_DRAW,
    353};
    354
    355static int
    356webcam_unbind(struct usb_composite_dev *cdev)
    357{
    358	if (!IS_ERR_OR_NULL(f_uvc))
    359		usb_put_function(f_uvc);
    360	if (!IS_ERR_OR_NULL(fi_uvc))
    361		usb_put_function_instance(fi_uvc);
    362	return 0;
    363}
    364
    365static int
    366webcam_bind(struct usb_composite_dev *cdev)
    367{
    368	struct f_uvc_opts *uvc_opts;
    369	int ret;
    370
    371	fi_uvc = usb_get_function_instance("uvc");
    372	if (IS_ERR(fi_uvc))
    373		return PTR_ERR(fi_uvc);
    374
    375	uvc_opts = container_of(fi_uvc, struct f_uvc_opts, func_inst);
    376
    377	uvc_opts->streaming_interval = streaming_interval;
    378	uvc_opts->streaming_maxpacket = streaming_maxpacket;
    379	uvc_opts->streaming_maxburst = streaming_maxburst;
    380
    381	uvc_opts->fs_control = uvc_fs_control_cls;
    382	uvc_opts->ss_control = uvc_ss_control_cls;
    383	uvc_opts->fs_streaming = uvc_fs_streaming_cls;
    384	uvc_opts->hs_streaming = uvc_hs_streaming_cls;
    385	uvc_opts->ss_streaming = uvc_ss_streaming_cls;
    386
    387	/* Allocate string descriptor numbers ... note that string contents
    388	 * can be overridden by the composite_dev glue.
    389	 */
    390	ret = usb_string_ids_tab(cdev, webcam_strings);
    391	if (ret < 0)
    392		goto error;
    393	webcam_device_descriptor.iManufacturer =
    394		webcam_strings[USB_GADGET_MANUFACTURER_IDX].id;
    395	webcam_device_descriptor.iProduct =
    396		webcam_strings[USB_GADGET_PRODUCT_IDX].id;
    397	webcam_config_driver.iConfiguration =
    398		webcam_strings[STRING_DESCRIPTION_IDX].id;
    399
    400	/* Register our configuration. */
    401	if ((ret = usb_add_config(cdev, &webcam_config_driver,
    402					webcam_config_bind)) < 0)
    403		goto error;
    404
    405	usb_composite_overwrite_options(cdev, &coverwrite);
    406	INFO(cdev, "Webcam Video Gadget\n");
    407	return 0;
    408
    409error:
    410	usb_put_function_instance(fi_uvc);
    411	return ret;
    412}
    413
    414/* --------------------------------------------------------------------------
    415 * Driver
    416 */
    417
    418static struct usb_composite_driver webcam_driver = {
    419	.name		= "g_webcam",
    420	.dev		= &webcam_device_descriptor,
    421	.strings	= webcam_device_strings,
    422	.max_speed	= USB_SPEED_SUPER,
    423	.bind		= webcam_bind,
    424	.unbind		= webcam_unbind,
    425};
    426
    427module_usb_composite_driver(webcam_driver);
    428
    429MODULE_AUTHOR("Laurent Pinchart");
    430MODULE_DESCRIPTION("Webcam Video Gadget");
    431MODULE_LICENSE("GPL");
    432