diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 059242f..70252a3 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -27,6 +27,15 @@ config SND_USB_AUDIO
 config SND_USB_AUDIO_USE_MEDIA_CONTROLLER
 	bool
 
+config SND_EXYNOS_USB_AUDIO
+	tristate "EXYNOS USB Audio offloading module"
+	depends on SND_USB_AUDIO
+	help
+	 Say Y here to include support for Exynos USB Audio ABOX offloading.
+
+	 To compile this driver as a module, choose M here: the module
+	 will be called exynos-usb-audio-offloading.
+
 config SND_USB_UA101
 	tristate "Edirol UA-101/UA-1000 driver"
 	select SND_PCM
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 9ccb21a..bf019c7 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -28,6 +28,8 @@ snd-usbmidi-lib-objs := midi.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usbmidi-lib.o
+obj-$(CONFIG_SND_EXYNOS_USB_AUDIO) += exynos-usb-audio-offloading.o
+exynos-usb-audio-offloading-y += exynos_usb_audio.o
 
 obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o
 obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
diff --git a/sound/usb/exynos_usb_audio.c b/sound/usb/exynos_usb_audio.c
new file mode 100644
index 0000000..456cc78
--- /dev/null
+++ b/sound/usb/exynos_usb_audio.c
@@ -0,0 +1,560 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *   USB Audio offloading Driver for Exynos
+ *
+ *   Copyright (c) 2017 by Kyounghye Yun <k-hye.yun@samsung.com>
+ *
+ */
+
+
+#include <linux/bitops.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/usb.h>
+#include <linux/usb/audio.h>
+#include <linux/usb/audio-v2.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/completion.h>
+
+#include <sound/pcm.h>
+#include "../../../sound/usb/exynos_usb_audio.h"
+#include "usbaudio.h"
+#include "helper.h"
+#include "card.h"
+#include "quirks.h"
+
+static struct exynos_usb_audio *usb_audio;
+static struct snd_usb_audio_vendor_ops exynos_usb_audio_ops;
+
+struct hcd_hw_info *g_hwinfo;
+EXPORT_SYMBOL_GPL(g_hwinfo);
+int otg_connection;
+EXPORT_SYMBOL_GPL(otg_connection);
+int usb_audio_connection;
+EXPORT_SYMBOL_GPL(usb_audio_connection);
+
+static void exynos_usb_audio_set_device(struct usb_device *udev)
+{
+	usb_audio->udev = udev;
+	usb_audio->is_audio = 1;
+}
+
+static int exynos_usb_audio_unmap_all(void)
+{
+	/*
+	 * TODO: unmapping pcm buffer, usb descriptor, Device Context,
+	 * Input Context, ERST, URAM.
+	 */
+
+	return 0;
+}
+
+static int exynos_usb_audio_pcmbuf(struct usb_device *udev, int iface)
+{
+	if (!usb_audio->is_audio || !otg_connection)
+		return -1;
+
+	/*
+	 * TODO: Transmit the DRAM address that contains the xhci device
+	 * information,and the DMA address required for operation to the abox
+	 * usb f/w.
+	 */
+
+	return 0;
+}
+
+static int exynos_usb_audio_setrate(int iface, int rate, int alt)
+{
+	if (!usb_audio->is_audio || !otg_connection)
+		return -1;
+
+	/*
+	 * TODO: Notify the abox usb f/w the audio sample rate supported by
+	 * the interface of the connected audio device.
+	 */
+
+	return 0;
+}
+
+static int exynos_usb_audio_setintf(struct usb_device *udev, int iface, int alt, int direction)
+{
+	struct hcd_hw_info *hwinfo = g_hwinfo;
+	u64 in_offset, out_offset;
+
+	if (!usb_audio->pcm_open_done)
+		return -EPERM;
+
+	if (!usb_audio->is_audio || !otg_connection)
+		return -1;
+
+	if (direction) {
+		/* IN EP */
+		if (!usb_audio->indeq_map_done ||
+			(hwinfo->in_deq != hwinfo->old_in_deq)) {
+			/* TODO: Transmit pcm interface number, alt setting
+			 * number to abox usb f/w
+			 */
+			usb_audio->indeq_map_done = 1;
+			in_offset = hwinfo->in_deq % PAGE_SIZE;
+		}
+
+		if (hwinfo->fb_out_deq) {
+			if (!usb_audio->fb_outdeq_map_done ||
+					(hwinfo->fb_out_deq != hwinfo->fb_old_out_deq)) {
+				/* TODO: Transmit pcm interface number,
+				 * alt setting number to abox usb f/w
+				 */
+				usb_audio->fb_outdeq_map_done = 1;
+				out_offset = hwinfo->fb_out_deq % PAGE_SIZE;
+			}
+		}
+	} else {
+		/* OUT EP */
+		if (!usb_audio->outdeq_map_done ||
+			(hwinfo->out_deq != hwinfo->old_out_deq)) {
+			/* TODO: Transmit pcm interface number, alt setting
+			 * number to abox usb f/w
+			 */
+			usb_audio->outdeq_map_done = 1;
+			out_offset = hwinfo->out_deq % PAGE_SIZE;
+		}
+
+		if (hwinfo->fb_in_deq) {
+			if (!usb_audio->fb_indeq_map_done ||
+					(hwinfo->fb_in_deq != hwinfo->fb_old_in_deq)) {
+				/* TODO: Transmit pcm interface number,
+				 * alt setting number to abox usb f/w
+				 */
+				usb_audio->fb_indeq_map_done = 1;
+				in_offset = hwinfo->fb_in_deq % PAGE_SIZE;
+			}
+		}
+	}
+
+	/* one more check connection to prevent kernel panic */
+	if (!usb_audio->is_audio || !otg_connection)
+		return -1;
+
+	/* TODO: Notify abox usb f/w a dequeue pointer */
+
+	return 0;
+}
+
+static int exynos_usb_audio_hcd(struct usb_device *udev)
+{
+	struct hcd_hw_info *hwinfo = g_hwinfo;
+
+	/* back up each address for unmap */
+	usb_audio->dcbaa_dma = hwinfo->dcbaa_dma;
+	usb_audio->save_dma = hwinfo->save_dma;
+	usb_audio->in_ctx = hwinfo->in_ctx;
+	usb_audio->out_ctx = hwinfo->out_ctx;
+	usb_audio->erst_addr = hwinfo->erst_addr;
+	usb_audio->speed = hwinfo->speed;
+	usb_audio->use_uram = hwinfo->use_uram;
+
+	/*
+	 * TODO: DCBAA, Device Context, Input Context, URAM, ERST mapping
+	 * and notify abox usb f/w the address about xhci h/w resource to
+	 * directly control the xhci in abox.
+	 */
+
+	return 0;
+}
+
+static int exynos_usb_audio_desc(struct usb_device *udev)
+{
+	int configuration, cfgno, i;
+	unsigned char *buffer;
+	u64 desc_addr;
+	u64 offset;
+
+	configuration = usb_choose_configuration(udev);
+
+	cfgno = -1;
+	for (i = 0; i < udev->descriptor.bNumConfigurations; i++) {
+		if (udev->config[i].desc.bConfigurationValue ==
+				configuration) {
+			cfgno = i;
+			break;
+		}
+	}
+
+	if (cfgno == -1)
+		cfgno = 0;
+
+	/* need to memory mapping for usb descriptor */
+	buffer = udev->rawdescriptors[cfgno];
+	desc_addr = virt_to_phys(buffer);
+	offset = desc_addr % PAGE_SIZE;
+
+	/* store address information */
+	usb_audio->desc_addr = desc_addr;
+	usb_audio->offset = offset;
+
+	desc_addr -= offset;
+
+	/*
+	 * TODO: Notify the abox usb f/w that all descriptors have been recived
+	 * from the connected usb audio device, and that copy and memory mapping
+	 * have beed completed so that it can be used in abox usb f/w
+	 */
+
+	return 0;
+}
+
+static int exynos_usb_audio_conn(struct usb_device *udev, int is_conn)
+{
+
+	/* TODO: Notify abox usb f/w whether usb device is connected or not */
+	if (!is_conn) {
+		if (usb_audio->is_audio) {
+			usb_audio->is_audio = 0;
+			usb_audio->usb_audio_state = USB_AUDIO_REMOVING;
+		}
+	} else {
+		cancel_work_sync(&usb_audio->usb_work);
+		usb_audio->indeq_map_done = 0;
+		usb_audio->outdeq_map_done = 0;
+		usb_audio->fb_indeq_map_done = 0;
+		usb_audio->fb_outdeq_map_done = 0;
+		usb_audio->pcm_open_done = 0;
+		reinit_completion(&usb_audio->discon_done);
+		usb_audio->usb_audio_state = USB_AUDIO_CONNECT;
+		usb_audio_connection = 1;
+	}
+
+	return 0;
+}
+
+static int exynos_usb_audio_pcm(bool is_open, bool direction)
+{
+	if (!usb_audio->is_audio || !otg_connection)
+		return -1;
+
+	if (is_open)
+		usb_audio->pcm_open_done = 1;
+
+	/* TODO: Notify the abox usb f/w the pcm open/close status */
+
+	return 0;
+}
+
+static void exynos_usb_audio_work(struct work_struct *w)
+{
+	/* Don't unmap in USB_AUDIO_TIMEOUT_PROBE state */
+	if (usb_audio->usb_audio_state != USB_AUDIO_REMOVING)
+		return;
+
+	exynos_usb_audio_unmap_all();
+	usb_audio->usb_audio_state = USB_AUDIO_DISCONNECT;
+	usb_audio_connection = 0;
+	complete(&usb_audio->discon_done);
+}
+
+static int exynos_usb_scenario_ctl_info(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = AUDIO_MODE_NORMAL;
+	uinfo->value.integer.max = AUDIO_MODE_CALL_SCREEN;
+	return 0;
+}
+
+static int exynos_usb_scenario_ctl_get(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol)
+{
+	struct exynos_usb_audio *usb = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = usb->user_scenario;
+	return 0;
+}
+
+static int exynos_usb_scenario_ctl_put(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol)
+{
+	struct exynos_usb_audio *usb = snd_kcontrol_chip(kcontrol);
+	int changed = 0;
+
+	if (usb->user_scenario !=
+	     ucontrol->value.integer.value[0]) {
+		usb->user_scenario = ucontrol->value.integer.value[0];
+		changed = 1;
+	}
+
+	return changed;
+}
+
+static int exynos_usb_add_ctls(struct snd_usb_audio *chip,
+				unsigned long private_value)
+{
+	struct snd_kcontrol_new knew = {
+		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+		.name = "USB Audio Mode",
+		.info = exynos_usb_scenario_ctl_info,
+		.get = exynos_usb_scenario_ctl_get,
+		.put = exynos_usb_scenario_ctl_put,
+	};
+
+	int err;
+
+	if (!chip)
+		return -ENODEV;
+
+	knew.private_value = private_value;
+	usb_audio->kctl = snd_ctl_new1(&knew, usb_audio);
+	if (!usb_audio->kctl)
+		return -ENOMEM;
+
+	err = snd_ctl_add(chip->card, usb_audio->kctl);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+int exynos_usb_audio_init(struct device *dev, struct platform_device *pdev)
+{
+	struct device_node *np = dev->of_node;
+	struct device_node *np_abox;
+	struct platform_device *pdev_abox;
+	int ret = 0;
+
+	if (!usb_audio) {
+		usb_audio = kmalloc(sizeof(struct exynos_usb_audio), GFP_KERNEL);
+		if (!usb_audio)
+			return -ENOMEM;
+	}
+
+	np_abox = of_parse_phandle(np, "abox", 0);
+	if (!np_abox)
+		return -EPROBE_DEFER;
+
+	pdev_abox = of_find_device_by_node(np_abox);
+	if (!pdev_abox)
+		return -EPROBE_DEFER;
+
+	init_completion(&usb_audio->in_conn_stop);
+	init_completion(&usb_audio->out_conn_stop);
+	init_completion(&usb_audio->discon_done);
+	usb_audio->abox = pdev_abox;
+	usb_audio->hcd_pdev = pdev;
+	usb_audio->udev = NULL;
+	usb_audio->is_audio = 0;
+	usb_audio->is_first_probe = 1;
+	usb_audio->user_scenario = AUDIO_MODE_NORMAL;
+	usb_audio->usb_audio_state = USB_AUDIO_DISCONNECT;
+	usb_audio_connection = 0;
+
+	INIT_WORK(&usb_audio->usb_work, exynos_usb_audio_work);
+
+	/* interface function mapping */
+	ret = snd_vendor_set_ops(&exynos_usb_audio_ops);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(exynos_usb_audio_init);
+
+/* card */
+static int exynos_usb_audio_connect(struct usb_interface *intf)
+{
+	struct usb_interface_descriptor *altsd;
+	struct usb_host_interface *alts;
+	struct usb_device *udev = interface_to_usbdev(intf);
+	int timeout = 0;
+
+	alts = &intf->altsetting[0];
+	altsd = get_iface_desc(alts);
+
+	if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
+		altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
+		altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
+	} else {
+		if (usb_audio->usb_audio_state == USB_AUDIO_REMOVING) {
+			timeout = wait_for_completion_timeout(
+				&usb_audio->discon_done,
+				msecs_to_jiffies(DISCONNECT_TIMEOUT));
+
+			if ((usb_audio->usb_audio_state == USB_AUDIO_REMOVING)
+					&& !timeout) {
+				usb_audio->usb_audio_state =
+					USB_AUDIO_TIMEOUT_PROBE;
+			}
+		}
+
+		if ((usb_audio->usb_audio_state == USB_AUDIO_DISCONNECT)
+			|| (usb_audio->usb_audio_state == USB_AUDIO_TIMEOUT_PROBE)) {
+			exynos_usb_audio_set_device(udev);
+			exynos_usb_audio_hcd(udev);
+			exynos_usb_audio_conn(udev, 1);
+			exynos_usb_audio_desc(udev);
+		} else {
+			return -EPERM;
+		}
+	}
+
+	return 0;
+}
+
+static void exynos_usb_audio_disconn(struct usb_interface *intf)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+
+	exynos_usb_audio_conn(udev, 0);
+}
+
+/* clock */
+static int exynos_usb_audio_set_interface(struct usb_device *udev,
+		struct usb_host_interface *alts, int iface, int alt)
+{
+	unsigned char ep;
+	unsigned char numEndpoints;
+	int direction;
+	int i;
+	int ret = 0;
+
+	if (alts != NULL) {
+		numEndpoints = get_iface_desc(alts)->bNumEndpoints;
+		if (numEndpoints < 1)
+			return -22;
+		if (numEndpoints == 1)
+			ep = get_endpoint(alts, 0)->bEndpointAddress;
+		else {
+			for (i = 0; i < numEndpoints; i++) {
+				ep = get_endpoint(alts, i)->bmAttributes;
+				if (!(ep & 0x30)) {
+					ep = get_endpoint(alts, i)->bEndpointAddress;
+					break;
+				}
+			}
+		}
+		if (ep & USB_DIR_IN)
+			direction = SNDRV_PCM_STREAM_CAPTURE;
+		else
+			direction = SNDRV_PCM_STREAM_PLAYBACK;
+
+		ret = exynos_usb_audio_setintf(udev, iface, alt, direction);
+	}
+
+	return ret;
+}
+
+/* pcm */
+static int exynos_usb_audio_set_rate(int iface, int rate, int alt)
+{
+	int ret;
+
+	ret = exynos_usb_audio_setrate(iface, rate, alt);
+
+	return ret;
+}
+
+static int exynos_usb_audio_set_pcmbuf(struct usb_device *dev, int iface)
+{
+	int ret;
+
+	ret = exynos_usb_audio_pcmbuf(dev, iface);
+
+	return ret;
+}
+
+static int exynos_usb_audio_set_pcm_intf(struct usb_interface *intf,
+					int iface, int alt, int direction)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	int ret;
+
+	ret = exynos_usb_audio_setintf(udev, iface, alt, direction);
+
+	return ret;
+}
+
+static int exynos_usb_audio_pcm_control(struct usb_device *udev,
+			enum snd_vendor_pcm_open_close onoff, int direction)
+{
+	int ret = 0;
+
+	if (onoff == 1) {
+		ret = exynos_usb_audio_pcm(1, direction);
+	} else if (onoff == 0) {
+		if (direction == SNDRV_PCM_STREAM_PLAYBACK)
+			reinit_completion(&usb_audio->out_conn_stop);
+		else if (direction == SNDRV_PCM_STREAM_CAPTURE)
+			reinit_completion(&usb_audio->in_conn_stop);
+
+		if (!usb_audio->pcm_open_done)
+			return 0;
+
+		ret = exynos_usb_audio_pcm(0, direction);
+	}
+
+	return ret;
+}
+
+static int exynos_usb_audio_add_control(struct snd_usb_audio *chip)
+{
+	int ret;
+
+	if (chip != NULL)
+		ret = exynos_usb_add_ctls(chip, 0);
+	else
+		ret = usb_audio->user_scenario;
+
+	return ret;
+}
+
+static int exynos_usb_audio_set_pcm_binterval(const struct audioformat *fp,
+				 const struct audioformat *found,
+				 int *cur_attr, int *attr)
+{
+	if (usb_audio->user_scenario >= AUDIO_MODE_IN_CALL) {
+		if (fp->datainterval < found->datainterval) {
+			found = fp;
+			cur_attr = attr;
+		}
+	} else {
+		if (fp->datainterval > found->datainterval) {
+			found = fp;
+			cur_attr = attr;
+		}
+	}
+
+	return 0;
+}
+
+/* Set interface function */
+static struct snd_usb_audio_vendor_ops exynos_usb_audio_ops = {
+	/* card */
+	.connect = exynos_usb_audio_connect,
+	.disconnect = exynos_usb_audio_disconn,
+	/* clock */
+	.set_interface = exynos_usb_audio_set_interface,
+	/* pcm */
+	.set_rate = exynos_usb_audio_set_rate,
+	.set_pcm_buf = exynos_usb_audio_set_pcmbuf,
+	.set_pcm_intf = exynos_usb_audio_set_pcm_intf,
+	.set_pcm_connection = exynos_usb_audio_pcm_control,
+	.set_pcm_binterval = exynos_usb_audio_set_pcm_binterval,
+	.usb_add_ctls = exynos_usb_audio_add_control,
+};
+
+int exynos_usb_audio_exit(void)
+{
+	/* future use */
+	return 0;
+}
+EXPORT_SYMBOL_GPL(exynos_usb_audio_exit);
+
+MODULE_AUTHOR("Jaehun Jung <jh0801.jung@samsung.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Exynos USB Audio offloading driver");
+
diff --git a/sound/usb/exynos_usb_audio.h b/sound/usb/exynos_usb_audio.h
new file mode 100644
index 0000000..13707744
--- /dev/null
+++ b/sound/usb/exynos_usb_audio.h
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*   USB Audio Driver for Exynos
+ *
+ *   Copyright (c) 2017 by Kyounghye Yun <k-hye.yun@samsung.com>
+ *
+ */
+
+#ifndef __LINUX_USB_EXYNOS_AUDIO_H
+#define __LINUX_USB_EXYNOS_AUDIO_H
+
+#include "../../../sound/usb/usbaudio.h"
+
+/* for KM */
+
+#define USB_AUDIO_MEM_BASE	0xC0000000
+
+#define USB_AUDIO_SAVE_RESTORE	(USB_AUDIO_MEM_BASE)
+#define USB_AUDIO_DEV_CTX	(USB_AUDIO_SAVE_RESTORE+PAGE_SIZE)
+#define USB_AUDIO_INPUT_CTX	(USB_AUDIO_DEV_CTX+PAGE_SIZE)
+#define USB_AUDIO_OUT_DEQ	(USB_AUDIO_INPUT_CTX+PAGE_SIZE)
+#define USB_AUDIO_IN_DEQ	(USB_AUDIO_OUT_DEQ+PAGE_SIZE)
+#define USB_AUDIO_FBOUT_DEQ	(USB_AUDIO_IN_DEQ+PAGE_SIZE)
+#define USB_AUDIO_FBIN_DEQ	(USB_AUDIO_FBOUT_DEQ+PAGE_SIZE)
+#define USB_AUDIO_ERST		(USB_AUDIO_FBIN_DEQ+PAGE_SIZE)
+#define USB_AUDIO_DESC		(USB_AUDIO_ERST+PAGE_SIZE)
+#define USB_AUDIO_PCM_OUTBUF	(USB_AUDIO_MEM_BASE+0x100000)
+#define USB_AUDIO_PCM_INBUF	(USB_AUDIO_MEM_BASE+0x800000)
+
+#if defined(CONFIG_SOC_S5E9815)
+#define USB_AUDIO_XHCI_BASE	0x12210000
+#define USB_URAM_BASE		0x122a0000
+#define USB_URAM_SIZE		(SZ_1K * 24)
+#elif defined(CONFIG_SOC_S5E9935)
+#define USB_AUDIO_XHCI_BASE	0x10B00000
+#define USB_URAM_BASE		0x02a00000
+#define USB_URAM_SIZE		(SZ_1K * 24)
+#else
+#error
+#endif
+
+#define USB_AUDIO_CONNECT		(1 << 0)
+#define USB_AUDIO_REMOVING		(1 << 1)
+#define USB_AUDIO_DISCONNECT		(1 << 2)
+#define USB_AUDIO_TIMEOUT_PROBE	(1 << 3)
+
+#define DISCONNECT_TIMEOUT	(500)
+
+#define AUDIO_MODE_NORMAL		0
+#define AUDIO_MODE_RINGTONE		1
+#define AUDIO_MODE_IN_CALL		2
+#define AUDIO_MODE_IN_COMMUNICATION	3
+#define AUDIO_MODE_CALL_SCREEN		4
+
+#define	CALL_INTERVAL_THRESHOLD		3
+
+#define USB_AUDIO_CONNECT		(1 << 0)
+#define USB_AUDIO_REMOVING		(1 << 1)
+#define USB_AUDIO_DISCONNECT		(1 << 2)
+#define USB_AUDIO_TIMEOUT_PROBE	(1 << 3)
+
+#define DISCONNECT_TIMEOUT	(500)
+
+struct host_data {
+	dma_addr_t out_data_dma;
+	dma_addr_t in_data_dma;
+	void *out_data_addr;
+	void *in_data_addr;
+};
+
+extern struct host_data xhci_data;
+
+struct exynos_usb_audio {
+	struct usb_device *udev;
+	struct platform_device *abox;
+	struct platform_device *hcd_pdev;
+	struct mutex    lock;
+	struct work_struct usb_work;
+	struct completion in_conn_stop;
+	struct completion out_conn_stop;
+	struct completion discon_done;
+
+	u64 out_buf_addr;
+	u64 in_buf_addr;
+	u64 pcm_offset;
+	u64 desc_addr;
+	u64 offset;
+
+	/* for hw_info */
+	u64 dcbaa_dma;
+	u64 in_ctx;
+	u64 out_ctx;
+	u64 erst_addr;
+
+	int speed;
+	/* 1: in, 0: out */
+	int set_ep;
+	int is_audio;
+	int is_first_probe;
+	u8 indeq_map_done;
+	u8 outdeq_map_done;
+	u8 fb_indeq_map_done;
+	u8 fb_outdeq_map_done;
+	u32 pcm_open_done;
+	u32 usb_audio_state;
+
+	struct snd_kcontrol *kctl;
+	u32 user_scenario;
+
+	void *pcm_buf;
+	u64 save_dma;
+
+	bool use_uram;
+};
+
+struct hcd_hw_info {
+	/* for XHCI */
+	int slot_id;
+	dma_addr_t erst_addr;
+	dma_addr_t dcbaa_dma;
+	dma_addr_t in_ctx;
+	dma_addr_t out_ctx;
+	dma_addr_t save_dma;
+	u64 cmd_ring;
+	/* Data Stream EP */
+	u64 old_out_deq;
+	u64 old_in_deq;
+	u64 out_deq;
+	u64 in_deq;
+	int in_ep;
+	int out_ep;
+	/* feedback ep */
+	int fb_in_ep;
+	int fb_out_ep;
+	u64 fb_old_out_deq;
+	u64 fb_old_in_deq;
+	u64 fb_out_deq;
+	u64 fb_in_deq;
+	/* Device Common Information */
+	int speed;
+	void *out_buf;
+	u64 out_dma;
+	void *in_buf;
+	u64 in_dma;
+	int use_uram;
+	int rawdesc_length;
+};
+
+int exynos_usb_audio_init(struct device *dev, struct platform_device *pdev);
+int exynos_usb_audio_exit(void);
+#endif /* __LINUX_USB_EXYNOS_AUDIO_H */
