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

Commit 5a83d02c authored by Hemant Kumar's avatar Hemant Kumar Committed by Mayank Rana
Browse files

usb: gadget: f_gsi: Add support for gps function driver



gps usb functionality is implemented using qmi packets.
User space entity sends and receives QMI packets using
misc device named /dev/gps.

Change-Id: I73af1caa9b272597909199022739390274a4b034
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent ef02260a
Loading
Loading
Loading
Loading
+37 −3
Original line number Diff line number Diff line
@@ -1640,6 +1640,9 @@ static int gsi_function_ctrl_port_init(struct f_gsi *gsi)
	case USB_PROT_DPL_ETHER:
		cdev_name = ETHER_DPL_CTRL_NAME;
		break;
	case USB_PROT_GPS_CTRL:
		cdev_name = GSI_GPS_CTRL_NAME;
		break;
	default:
		break;
	}
@@ -2544,6 +2547,11 @@ static void gsi_suspend(struct usb_function *f)
		return;
	}

	if (!gsi->data_interface_up) {
		log_event_dbg("%s: suspend done\n", __func__);
		return;
	}

	block_db = true;
	usb_gsi_ep_op(gsi->d_port.in_ep, (void *)&block_db,
			GSI_EP_OP_SET_CLR_BLOCK_DBL);
@@ -2587,6 +2595,11 @@ static void gsi_resume(struct usb_function *f)
	/* Check any pending cpkt, and queue immediately on resume */
	gsi_ctrl_send_notification(gsi);

	if (!gsi->data_interface_up) {
		log_event_dbg("%s: resume done\n", __func__);
		return;
	}

	/*
	 * Linux host does not send RNDIS_MSG_INIT or non-zero
	 * RNDIS_MESSAGE_PACKET_FILTER after performing bus resume.
@@ -2886,9 +2899,11 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f)
			goto fail;
	}

	if (gsi->prot_id != USB_PROT_GPS_CTRL) {
		status = gsi->data_id = usb_interface_id(c, f);
		if (status < 0)
			goto fail;
	}

	switch (gsi->prot_id) {
	case USB_PROT_RNDIS_IPA:
@@ -3187,6 +3202,18 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f)
		info.notify_buf_len = sizeof(struct usb_cdc_notification);
		name = "dpl_usb";
		break;
	case USB_PROT_GPS_CTRL:
		info.string_defs = gps_string_defs;
		info.ctrl_str_idx = 0;
		info.ctrl_desc = &gps_interface_desc;
		info.fs_notify_desc = &gps_fs_notify_desc;
		info.hs_notify_desc = &gps_hs_notify_desc;
		info.ss_notify_desc = &gps_ss_notify_desc;
		info.fs_desc_hdr = gps_fs_function;
		info.hs_desc_hdr = gps_hs_function;
		info.ss_desc_hdr = gps_ss_function;
		info.notify_buf_len = sizeof(struct usb_cdc_notification);
		break;
	default:
		log_event_err("%s: Invalid prot id %d", __func__,
							gsi->prot_id);
@@ -3197,6 +3224,9 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f)
	if (status)
		goto dereg_rndis;

	if (gsi->prot_id == USB_PROT_GPS_CTRL)
		goto skip_ipa_init;

	if (is_ext_prot_ether(gsi->prot_id)) {
		if (!name)
			return -EINVAL;
@@ -3339,6 +3369,10 @@ static int gsi_bind_config(struct f_gsi *gsi)
		gsi->function.name = "dpl";
		gsi->function.strings = qdss_gsi_strings;
		break;
	case USB_PROT_GPS_CTRL:
		gsi->function.name = "gps";
		gsi->function.strings = gps_strings;
		break;
	default:
		log_event_err("%s: invalid prot id %d", __func__, gsi->prot_id);
		return -EINVAL;
+91 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#define GSI_DPL_CTRL_NAME "dpl_ctrl"
#define ETHER_RMNET_CTRL_NAME "rmnet_ctrl0"
#define ETHER_DPL_CTRL_NAME "dpl_ctrl0"
#define GSI_GPS_CTRL_NAME "gps"

#define GSI_CTRL_NAME_LEN (sizeof(GSI_MBIM_CTRL_NAME)+2)
#define GSI_MAX_CTRL_PKT_SIZE 8192
@@ -134,6 +135,7 @@ enum usb_prot_id {
	/* non-accelerated */
	USB_PROT_RMNET_ETHER,
	USB_PROT_DPL_ETHER,
	USB_PROT_GPS_CTRL,

	USB_PROT_MAX,
};
@@ -335,6 +337,8 @@ static int name_to_prot_id(const char *name)
		return USB_PROT_RMNET_ETHER;
	if (!strncasecmp(name, "dpl.ether", MAX_INST_NAME_LEN))
		return USB_PROT_DPL_ETHER;
	if (!strncasecmp(name, "gps", MAX_INST_NAME_LEN))
		return USB_PROT_GPS_CTRL;

error:
	return -EINVAL;
@@ -1434,4 +1438,91 @@ static struct usb_gadget_strings *qdss_gsi_strings[] = {
	&qdss_gsi_string_table,
	NULL,
};

/* gps device descriptor */
static struct usb_interface_descriptor gps_interface_desc = {
	.bLength =		USB_DT_INTERFACE_SIZE,
	.bDescriptorType =	USB_DT_INTERFACE,
	.bNumEndpoints =	1,
	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
	.bInterfaceSubClass =	USB_CLASS_VENDOR_SPEC,
	.bInterfaceProtocol =	USB_CLASS_VENDOR_SPEC,
	/* .iInterface = DYNAMIC */
};

/* Full speed support */
static struct usb_endpoint_descriptor gps_fs_notify_desc = {
	.bLength =		USB_DT_ENDPOINT_SIZE,
	.bDescriptorType =	USB_DT_ENDPOINT,
	.bEndpointAddress =	USB_DIR_IN,
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
	.wMaxPacketSize =	cpu_to_le16(MAX_NOTIFY_SIZE),
	.bInterval =		1 << LOG2_STATUS_INTERVAL_MSEC,
};

static struct usb_descriptor_header *gps_fs_function[] = {
	(struct usb_descriptor_header *) &gps_interface_desc,
	(struct usb_descriptor_header *) &gps_fs_notify_desc,
	NULL,
};

/* High speed support */
static struct usb_endpoint_descriptor gps_hs_notify_desc  = {
	.bLength =		USB_DT_ENDPOINT_SIZE,
	.bDescriptorType =	USB_DT_ENDPOINT,
	.bEndpointAddress =	USB_DIR_IN,
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
	.wMaxPacketSize =	cpu_to_le16(MAX_NOTIFY_SIZE),
	.bInterval =		LOG2_STATUS_INTERVAL_MSEC + 4,
};

static struct usb_descriptor_header *gps_hs_function[] = {
	(struct usb_descriptor_header *) &gps_interface_desc,
	(struct usb_descriptor_header *) &gps_hs_notify_desc,
	NULL,
};

/* Super speed support */
static struct usb_endpoint_descriptor gps_ss_notify_desc  = {
	.bLength =		USB_DT_ENDPOINT_SIZE,
	.bDescriptorType =	USB_DT_ENDPOINT,
	.bEndpointAddress =	USB_DIR_IN,
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
	.wMaxPacketSize =	cpu_to_le16(MAX_NOTIFY_SIZE),
	.bInterval =		LOG2_STATUS_INTERVAL_MSEC + 4,
};

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

	/* the following 3 values can be tweaked if necessary */
	/* .bMaxBurst =		0, */
	/* .bmAttributes =	0, */
	.wBytesPerInterval =	cpu_to_le16(MAX_NOTIFY_SIZE),
};

static struct usb_descriptor_header *gps_ss_function[] = {
	(struct usb_descriptor_header *) &gps_interface_desc,
	(struct usb_descriptor_header *) &gps_ss_notify_desc,
	(struct usb_descriptor_header *) &gps_ss_notify_comp_desc,
	NULL,
};

/* String descriptors */

static struct usb_string gps_string_defs[] = {
	[0].s = "GPS",
	{  } /* end of list */
};

static struct usb_gadget_strings gps_string_table = {
	.language =		0x0409,	/* en-us */
	.strings =		gps_string_defs,
};

static struct usb_gadget_strings *gps_strings[] = {
	&gps_string_table,
	NULL,
};
#endif