Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c07fc4d4 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: gadget: Support H264 format for f_uvc driver"

parents 74497b16 2165bc1a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -423,6 +423,7 @@ config USB_G_ANDROID
	select USB_F_NCM
	select USB_F_MASS_STORAGE
	select USB_F_UAC1 if SND_PCM
	select USB_F_UAC2 if SND_PCM
	select USB_F_UVC if MEDIA_SUPPORT
	help
	  The Android Composite Gadget supports multiple USB
+59 −0
Original line number Diff line number Diff line
@@ -1514,6 +1514,64 @@ static struct android_usb_function audio_function = {
};
#endif

/* PERIPHERAL uac2 */
struct uac2_function_config {
	struct usb_function *func;
	struct usb_function_instance *fi;
};

static int uac2_function_init(struct android_usb_function *f,
			       struct usb_composite_dev *cdev)
{
	struct uac2_function_config *config;

	f->config = kzalloc(sizeof(*config), GFP_KERNEL);
	if (!f->config)
		return -ENOMEM;

	config = f->config;

	config->fi = usb_get_function_instance("uac2");
	if (IS_ERR(config->fi))
		return PTR_ERR(config->fi);

	config->func = usb_get_function(config->fi);
	if (IS_ERR(config->func)) {
		usb_put_function_instance(config->fi);
		return PTR_ERR(config->func);
	}

	return 0;
}

static void uac2_function_cleanup(struct android_usb_function *f)
{
	struct uac2_function_config *config = f->config;

	if (config) {
		usb_put_function(config->func);
		usb_put_function_instance(config->fi);
	}

	kfree(f->config);
	f->config = NULL;
}

static int uac2_function_bind_config(struct android_usb_function *f,
					  struct usb_configuration *c)
{
	struct uac2_function_config *config = f->config;

	return usb_add_function(c, config->func);
}

static struct android_usb_function uac2_function = {
	.name		= "uac2_func",
	.init		= uac2_function_init,
	.cleanup	= uac2_function_cleanup,
	.bind_config	= uac2_function_bind_config,
};

#ifdef CONFIG_MEDIA_SUPPORT
/* PERIPHERAL VIDEO */
struct video_function_config {
@@ -3222,6 +3280,7 @@ static struct android_usb_function *default_functions[] = {
	&ecm_qc_function,
#ifdef CONFIG_SND_PCM
	&audio_function,
	&uac2_function,
#endif
#ifdef CONFIG_MEDIA_SUPPORT
	&video_function,
+50 −1
Original line number Diff line number Diff line
@@ -522,6 +522,7 @@ static int alsa_uac2_init(struct audio_dev *agdev)
	struct snd_uac2_chip *uac2 = &agdev->uac2;
	int err;

	memset(&uac2->pdev, 0, sizeof(uac2->pdev));
	uac2->pdrv.probe = snd_uac2_probe;
	uac2->pdrv.remove = snd_uac2_remove;
	uac2->pdrv.driver.name = uac2_name;
@@ -791,6 +792,13 @@ struct usb_endpoint_descriptor hs_epout_desc = {
	.bInterval = 4,
};

static struct usb_ss_ep_comp_descriptor ss_epout_comp_desc = {
	 .bLength =		 sizeof(ss_epout_comp_desc),
	 .bDescriptorType =	 USB_DT_SS_ENDPOINT_COMP,

	 .wBytesPerInterval =	cpu_to_le16(1024),
};

/* CS AS ISO OUT Endpoint */
static struct uac2_iso_endpoint_descriptor as_iso_out_desc = {
	.bLength = sizeof as_iso_out_desc,
@@ -868,6 +876,13 @@ struct usb_endpoint_descriptor hs_epin_desc = {
	.bInterval = 4,
};

static struct usb_ss_ep_comp_descriptor ss_epin_comp_desc = {
	 .bLength =		 sizeof(ss_epin_comp_desc),
	 .bDescriptorType =	 USB_DT_SS_ENDPOINT_COMP,

	 .wBytesPerInterval =	cpu_to_le16(1024),
};

/* CS AS ISO IN Endpoint */
static struct uac2_iso_endpoint_descriptor as_iso_in_desc = {
	.bLength = sizeof as_iso_in_desc,
@@ -940,6 +955,38 @@ static struct usb_descriptor_header *hs_audio_desc[] = {
	NULL,
};

static struct usb_descriptor_header *ss_audio_desc[] = {
	(struct usb_descriptor_header *)&iad_desc,
	(struct usb_descriptor_header *)&std_ac_if_desc,

	(struct usb_descriptor_header *)&ac_hdr_desc,
	(struct usb_descriptor_header *)&in_clk_src_desc,
	(struct usb_descriptor_header *)&out_clk_src_desc,
	(struct usb_descriptor_header *)&usb_out_it_desc,
	(struct usb_descriptor_header *)&io_in_it_desc,
	(struct usb_descriptor_header *)&usb_in_ot_desc,
	(struct usb_descriptor_header *)&io_out_ot_desc,

	(struct usb_descriptor_header *)&std_as_out_if0_desc,
	(struct usb_descriptor_header *)&std_as_out_if1_desc,

	(struct usb_descriptor_header *)&as_out_hdr_desc,
	(struct usb_descriptor_header *)&as_out_fmt1_desc,
	(struct usb_descriptor_header *)&hs_epout_desc,
	(struct usb_descriptor_header *)&ss_epout_comp_desc,
	(struct usb_descriptor_header *)&as_iso_out_desc,

	(struct usb_descriptor_header *)&std_as_in_if0_desc,
	(struct usb_descriptor_header *)&std_as_in_if1_desc,

	(struct usb_descriptor_header *)&as_in_hdr_desc,
	(struct usb_descriptor_header *)&as_in_fmt1_desc,
	(struct usb_descriptor_header *)&hs_epin_desc,
	(struct usb_descriptor_header *)&ss_epin_comp_desc,
	(struct usb_descriptor_header *)&as_iso_in_desc,
	NULL,
};

struct cntrl_cur_lay3 {
	__u32	dCUR;
};
@@ -1030,6 +1077,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
		return ret;
	}
	std_ac_if_desc.bInterfaceNumber = ret;
	iad_desc.bFirstInterface = ret;
	agdev->ac_intf = ret;
	agdev->ac_alt = 0;

@@ -1075,7 +1123,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
	hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
	hs_epin_desc.wMaxPacketSize = fs_epin_desc.wMaxPacketSize;

	ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL);
	ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc,
					 ss_audio_desc);
	if (ret)
		goto err;

+3 −3
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ static struct usb_interface_descriptor uvc_control_intf = {
	.bNumEndpoints		= 1,
	.bInterfaceClass	= USB_CLASS_VIDEO,
	.bInterfaceSubClass	= UVC_SC_VIDEOCONTROL,
	.bInterfaceProtocol	= 0x00,
	.bInterfaceProtocol	= 0x01,
	.iInterface		= 0,
};

@@ -121,7 +121,7 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt0 = {
	.bNumEndpoints		= 0,
	.bInterfaceClass	= USB_CLASS_VIDEO,
	.bInterfaceSubClass	= UVC_SC_VIDEOSTREAMING,
	.bInterfaceProtocol	= 0x00,
	.bInterfaceProtocol	= 0x01,
	.iInterface		= 0,
};

@@ -133,7 +133,7 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt1 = {
	.bNumEndpoints		= 1,
	.bInterfaceClass	= USB_CLASS_VIDEO,
	.bInterfaceSubClass	= UVC_SC_VIDEOSTREAMING,
	.bInterfaceProtocol	= 0x00,
	.bInterfaceProtocol	= 0x01,
	.iInterface		= 0,
};

+102 −8
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = {
	.bLength		= UVC_DT_HEADER_SIZE(1),
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VC_HEADER,
	.bcdUVC			= cpu_to_le16(0x0100),
	.bcdUVC			= cpu_to_le16(0x0150),
	.wTotalLength		= 0, /* dynamic */
	.dwClockFrequency	= cpu_to_le32(48000000),
	.bInCollection		= 0, /* dynamic */
@@ -52,7 +52,7 @@ static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = {
	.wObjectiveFocalLengthMax	= cpu_to_le16(0),
	.wOcularFocalLength		= cpu_to_le16(0),
	.bControlSize		= 3,
	.bmControls[0]		= 2,
	.bmControls[0]		= 14,
	.bmControls[1]		= 0,
	.bmControls[2]		= 0,
};
@@ -65,8 +65,8 @@ static const struct uvc_processing_unit_descriptor uvc_processing = {
	.bSourceID		= 1,
	.wMaxMultiplier		= cpu_to_le16(16*1024),
	.bControlSize		= 2,
	.bmControls[0]		= 1,
	.bmControls[1]		= 0,
	.bmControls[0]		= 64,
	.bmControls[1]		= 16,
	.iProcessing		= 0,
};

@@ -81,13 +81,13 @@ static const struct uvc_output_terminal_descriptor uvc_output_terminal = {
	.iTerminal		= 0,
};

DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 2);
DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 3);

static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = {
	.bLength		= UVC_DT_INPUT_HEADER_SIZE(1, 2),
static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 3) uvc_input_header = {
	.bLength		= UVC_DT_INPUT_HEADER_SIZE(1, 3),
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VS_INPUT_HEADER,
	.bNumFormats		= 2,
	.bNumFormats		= 3,
	.wTotalLength		= 0, /* dynamic */
	.bEndpointAddress	= 0, /* dynamic */
	.bmInfo			= 0,
@@ -98,6 +98,7 @@ static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = {
	.bControlSize		= 1,
	.bmaControls[0][0]	= 0,
	.bmaControls[1][0]	= 4,
	.bmaControls[2][0]	= 0,
};

static const struct uvc_format_uncompressed uvc_format_yuv = {
@@ -205,6 +206,90 @@ static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = {
	.dwFrameInterval[0]	= cpu_to_le32(5000000),
};

static const struct uvc_format_h264 uvc_fmt_h264 = {
	.bLength				= UVC_DT_FORMAT_H264_SIZE,
	.bDescriptorType			= USB_DT_CS_INTERFACE,
	.bDescriptorSubType			= UVC_VS_FORMAT_H264,
	.bFormatIndex				= 3,
	.bNumFrameDescriptors			= 2,
	.bDefaultFrameIndex			= 1,
	.bMaxCodecConfigDelay			= 0x4,
	.bmSupportedSliceModes			= 0,
	.bmSupportedSyncFrameTypes		= 0x76,
	.bResolutionScaling			= 0,
	.Reserved1				= 0,
	.bmSupportedRateControlModes		= 0x3F,
	.wMaxMBperSecOneResNoScalability	= cpu_to_le16(972),
	.wMaxMBperSecTwoResNoScalability	= 0,
	.wMaxMBperSecThreeResNoScalability	= 0,
	.wMaxMBperSecFourResNoScalability	= 0,
	.wMaxMBperSecOneResTemporalScalability	= cpu_to_le16(972),
	.wMaxMBperSecTwoResTemporalScalability	= 0,
	.wMaxMBperSecThreeResTemporalScalability	= 0,
	.wMaxMBperSecFourResTemporalScalability		= 0,
	.wMaxMBperSecOneResTemporalQualityScalability	= cpu_to_le16(972),
	.wMaxMBperSecTwoResTemporalQualityScalability	= 0,
	.wMaxMBperSecThreeResTemporalQualityScalability	= 0,
	.wMaxMBperSecFourResTemporalQualityScalability	= 0,
	.wMaxMBperSecOneResTemporalSpatialScalability	= 0,
	.wMaxMBperSecTwoResTemporalSpatialScalability	= 0,
	.wMaxMBperSecThreeResTemporalSpatialScalability	= 0,
	.wMaxMBperSecFourResTemporalSpatialScalability	= 0,
	.wMaxMBperSecOneResFullScalability		= 0,
	.wMaxMBperSecTwoResFullScalability		= 0,
	.wMaxMBperSecThreeResFullScalability		= 0,
	.wMaxMBperSecFourResFullScalability		= 0,
};

DECLARE_UVC_FRAME_H264(1);
DECLARE_UVC_FRAME_H264(3);

static const struct UVC_FRAME_H264(1) uvc_frame_h264_1920p = {
	.bLength		= UVC_DT_FRAME_H264_SIZE(1),
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VS_FRAME_H264,
	.bFrameIndex		= 1,
	.wWidth			= cpu_to_le16(3840),
	.wHeight		= cpu_to_le16(1920),
	.wSARwidth		= 0,
	.wSARheight		= 0,
	.wProfile		= 0x6400,
	.bLevelIDC		= 0x33,
	.bmSupportedUsages	= 0x70003,
	.wConstrainedToolset	= cpu_to_le16(0),
	.bmCapabilities		= 0x47,
	.bmSVCCapabilities	= 0x4,
	.bmMVCCapabilities	= 0,
	.dwMinBitRate		= cpu_to_le16(29491200),
	.dwMaxBitRate		= cpu_to_le16(100000000),
	.dwDefaultFrameInterval	= cpu_to_le16(333667),
	.bNumFrameIntervals	= 1,
	.dwFrameInterval[0]	= cpu_to_le16(333667),
};

static const struct UVC_FRAME_H264(3) uvc_frame_h264_960p = {
	.bLength		= UVC_DT_FRAME_H264_SIZE(3),
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VS_FRAME_H264,
	.bFrameIndex		= 2,
	.wWidth			= cpu_to_le16(1920),
	.wHeight		= cpu_to_le16(960),
	.wSARwidth		= 0,
	.wSARheight		= 0,
	.wProfile		= 0x6400,
	.bLevelIDC		= 0x28,
	.bmSupportedUsages	= 0x70003,
	.wConstrainedToolset	= cpu_to_le16(0),
	.bmCapabilities		= 0x47,
	.bmSVCCapabilities	= 0x4,
	.bmMVCCapabilities	= 0,
	.dwMinBitRate		= cpu_to_le16(29491200),
	.dwMaxBitRate		= cpu_to_le16(100000000),
	.dwDefaultFrameInterval	= cpu_to_le16(333667),
	.bNumFrameIntervals	= 1,
	.dwFrameInterval[0]	= cpu_to_le16(333667),
};

static const struct uvc_color_matching_descriptor uvc_color_matching = {
	.bLength		= UVC_DT_COLOR_MATCHING_SIZE,
	.bDescriptorType	= USB_DT_CS_INTERFACE,
@@ -238,6 +323,9 @@ static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = {
	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
	(const struct uvc_descriptor_header *) &uvc_fmt_h264,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_960p,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_1920p,
	(const struct uvc_descriptor_header *) &uvc_color_matching,
	NULL,
};
@@ -250,6 +338,9 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
	(const struct uvc_descriptor_header *) &uvc_fmt_h264,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_960p,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_1920p,
	(const struct uvc_descriptor_header *) &uvc_color_matching,
	NULL,
};
@@ -262,6 +353,9 @@ static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = {
	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
	(const struct uvc_descriptor_header *) &uvc_fmt_h264,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_960p,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_1920p,
	(const struct uvc_descriptor_header *) &uvc_color_matching,
	NULL,
};
Loading