From patchwork Thu Mar 24 08:10:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oh Eomji X-Patchwork-Id: 554403 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BEBC3C433EF for ; Thu, 24 Mar 2022 08:13:58 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id DBDAB1785; Thu, 24 Mar 2022 09:13:06 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz DBDAB1785 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1648109636; bh=5mug3O3l1T0hL2JQbLe2S5+hVq8pBzaJF4xmHRu/ONA=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=L4Tph+UEK/0RUgiVTeegNnFHeDmQpY+AHvO53gVuGxG49i8fdsuwlcYWLW0fnzgmy 0KGSf4D4aXN7gtJkuaD4Q4GqJhx1O+Mn8jAPsqJTrhjbRc4z3f0wI5umFNTJ/gLyAM juKmNA6EVKVyVZhfdMIki5FZjf0kAD9Z8aDiMsJw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 247C8F80515; Thu, 24 Mar 2022 09:12:32 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id AEB47F800AA; Thu, 24 Mar 2022 09:12:30 +0100 (CET) Received: from mailout3.samsung.com (mailout3.samsung.com [203.254.224.33]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 4AD96F800AA for ; Thu, 24 Mar 2022 09:12:22 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 4AD96F800AA Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="aRsLWbsO" Received: from epcas2p4.samsung.com (unknown [182.195.41.56]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20220324081218epoutp03aab703f58cd4ce2ff4642a822e129f5a~fQuSg2xAW3184031840epoutp03C for ; Thu, 24 Mar 2022 08:12:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20220324081218epoutp03aab703f58cd4ce2ff4642a822e129f5a~fQuSg2xAW3184031840epoutp03C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1648109538; bh=ijbZIdlZTCT7owCfx0etBk42pkcgnP7rXEjmEjUQen0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aRsLWbsOCFr+KM71VMtOqIXSwFTeuuct5sfUu176R211iOwKSFpivnWodQ10ttnhq 3pHetOjIhjcFcopqD3pXO6/Ogay0gAAZfzD4qzZyWq0cYEJeORS/4BvEFdymDCijj9 FgqKFelZiy1pVopJ2BM9eOGrfzOqhM4lQ5j6o1hM= Received: from epsnrtp2.localdomain (unknown [182.195.42.163]) by epcas2p3.samsung.com (KnoxPortal) with ESMTP id 20220324081217epcas2p39aab5559a3aaa58eb6bd3f24a0528fc6~fQuSBpy-40248902489epcas2p3P; Thu, 24 Mar 2022 08:12:17 +0000 (GMT) Received: from epsmges2p4.samsung.com (unknown [182.195.36.101]) by epsnrtp2.localdomain (Postfix) with ESMTP id 4KPHy542kfz4x9QY; Thu, 24 Mar 2022 08:12:13 +0000 (GMT) Received: from epcas2p1.samsung.com ( [182.195.41.53]) by epsmges2p4.samsung.com (Symantec Messaging Gateway) with SMTP id 3B.46.33036.DD72C326; Thu, 24 Mar 2022 17:12:13 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas2p4.samsung.com (KnoxPortal) with ESMTPA id 20220324081212epcas2p4d2ed1f3a1bb020606cf65016efec085b~fQuNevaXy1700917009epcas2p4Q; Thu, 24 Mar 2022 08:12:12 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20220324081212epsmtrp13a53318264a2e4613cf6d2a0b6556e09~fQuNd0RiZ0321203212epsmtrp1W; Thu, 24 Mar 2022 08:12:12 +0000 (GMT) X-AuditID: b6c32a48-4fbff7000000810c-c5-623c27dd23eb Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id E8.5E.29871.CD72C326; Thu, 24 Mar 2022 17:12:12 +0900 (KST) Received: from ubuntu.dsn.sec.samsung.com (unknown [12.36.155.120]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20220324081212epsmtip24cf9df23301dd8c54dfcd10de71ee888~fQuNLnDwi1325613256epsmtip2R; Thu, 24 Mar 2022 08:12:12 +0000 (GMT) From: Oh Eomji To: Jaroslav Kysela , Takashi Iwai , Greg Kroah-Hartman Subject: [PATCH v1 1/3] sound: usb: Add vendor's hooking interface Date: Thu, 24 Mar 2022 17:10:42 +0900 Message-Id: <1648109444-196321-2-git-send-email-eomji.oh@samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1648109444-196321-1-git-send-email-eomji.oh@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrEKsWRmVeSWpSXmKPExsWy7bCmqe5ddZskgxXH+S2uXDzEZHFq+UIm i+bF69ks7j78wWIx5ddSZovLu+awWRz4s5jNonNXP6vFhu9rGR04PTZ8bmLz2DnrLrvHplWd bB77565h99j3dhmbR9+WVYwe67dcZfH4vEkugCMq2yYjNTEltUghNS85PyUzL91WyTs43jne 1MzAUNfQ0sJcSSEvMTfVVsnFJ0DXLTMH6D4lhbLEnFKgUEBicbGSvp1NUX5pSapCRn5xia1S akFKToF5gV5xYm5xaV66Xl5qiZWhgYGRKVBhQnbGtVX/mQvuOVZM+LyRpYHxpmkXIyeHhICJ RMea7ewgtpDADkaJGf2KXYxcQPYnRokdJ7vZIZxvjBKT1q1jhen492gGC0RiL6PEhgXLWCGc H4wS3T9mMYFUsQmoSkxftp2xi5GDQ0SgTGLZdEuQGmaB+0A16y6xgdQICzhJXOzexQhiswDV X13fCmbzCrhKXD/TzQaxTU7i5rlOZpA5nAJuEr9euoPMkRB4yy7RNGsFWFxCwEXi4gU/iHJh iVfHt7BD2FISL/vboOxiiYMLnkONrJF4e7AVKm4sMetZO9iZzAKaEut36UNMVJY4cosFpIJZ gE+i4/Bfdogwr0RHmxBEo5LEpKZOJghbQmLF5yYo20PixMyjTJAAmcko0TlhIcsERrlZCAsW MDKuYhRLLSjOTU8tNiowgUdXcn7uJkZw4tPy2ME4++0HvUOMTByMhxglOJiVRHjvX7ZOEuJN SaysSi3Kjy8qzUktPsRoCgy5icxSosn5wNSbVxJvaGJpYGJmZmhuZGpgriTO65WyIVFIID2x JDU7NbUgtQimj4mDU6qBKSNKSDrq/Iv13x/4Hjmona92P3C59ynZaxcOtvQ9TdfMm13nJvrM 63NaibBrx9WatevjHmhs/fn9c/4fVqXlOfvfiB361XV+rimv7QruyPQu7ytZaybcmlHfMPFC SNgWv8xIB7HO4MbDamkrmJd+XFw4dd6Dw3X6H+TNBVnMLjLJPzYNyqvluvB+dnpPYcZ5Jn7P nz/533KumOdpdi6/V9TzksRMznDfLyv22K1sZxCzWX1Z4nhfndmuuZ4KdmorHHZwHyvgOKF7 P6vRa32myYwErs6GrY26ih7HFvI80DJlX/SPO38Kr4Lg/HjF/xazn8qd/Drvw27Ru/kdk5g5 d0tf4tC8eOXpiStbhctSlFiKMxINtZiLihMBSBhCdQUEAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrPLMWRmVeSWpSXmKPExsWy7bCSvO4ddZskg87v+hZXLh5isji1fCGT RfPi9WwWdx/+YLGY8msps8XlXXPYLA78Wcxm0bmrn9Viw/e1jA6cHhs+N7F57Jx1l91j06pO No/9c9ewe+x7u4zNo2/LKkaP9Vuusnh83iQXwBHFZZOSmpNZllqkb5fAlXFt1X/mgnuOFRM+ b2RpYLxp2sXIySEhYCLx79EMli5GLg4hgd2MErdev2CDSEhILOh6zQxhC0vcbznCCmILCXxj lJh/yQnEZhNQlZi+bDsjiC0iUCFx6+t2ZpBBzAJPGSUWTrgB1iws4CRxsXsXWBELUMPV9a1g Nq+Aq8T1M91Qy+Qkbp7rBKrn4OAUcJP49dIdYperRP/LfWwTGPkWMDKsYpRMLSjOTc8tNiww zEst1ytOzC0uzUvXS87P3cQIDlMtzR2M21d90DvEyMTBeIhRgoNZSYT3/mXrJCHelMTKqtSi /Pii0pzU4kOM0hwsSuK8F7pOxgsJpCeWpGanphakFsFkmTg4pRqY5Aw2v2FYv0fB+k50QcHB I937dteK/AmTSHS1YL7Ickv3wbzlE+0qJtvxyuRenRX9K2W54NWpJb17sqO+Xfn1oiuu44wL a4mlS3yqxZOEVcbfdtmdVKpbtegSk33eu4C9lfaRod8yV/959uNLRH2a6c0AI5vWn1/Vlhvc 4d0bdWeHZtztkmveBxfHdv/Tk9r08FbbrbJw9VANndCQR5l/Auofn7vjt5bXKOkHr9ASsR5Z D35T09Tl76bMXSLVz63Vq9B+8vhN6Z7sQ5skXlX3bnp7mGnvuXaf4J/hmQxJbB2HVLZMiL9e EvnsZevSwO7LPnlpvDoM8oy3lfrX9G5x0WFeMu1A7McezY42E18lluKMREMt5qLiRADqA0YV wgIAAA== X-CMS-MailID: 20220324081212epcas2p4d2ed1f3a1bb020606cf65016efec085b X-Msg-Generator: CA X-Sendblock-Type: AUTO_CONFIDENTIAL CMS-TYPE: 102P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20220324081212epcas2p4d2ed1f3a1bb020606cf65016efec085b References: <1648109444-196321-1-git-send-email-eomji.oh@samsung.com> Cc: alsa-devel@alsa-project.org, JaeHun Jung , Leon Romanovsky , Pavel Skripkin , open list , Oh Eomji X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" In mobile, a co-processor can be used with USB audio to improve power consumption. To support this type of hardware, hooks need to be added to the USB audio subsystem to be able to call into the hardware when needed. The main operation of the call-backs are: - Initialize the co-processor by transmitting data when initializing. - Change the co-processor setting value through the interface function. - Configure sampling rate - pcm open/close - other housekeeping Known issues: - This only supports one set of callback hooks, meaning that this only works if there is one type of USB controller in the system. This should be changed to be a per-host-controller interface instead of one global set of callbacks. Signed-off-by: JaeHun Jung Signed-off-by: Oh Eomji --- sound/usb/card.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ sound/usb/card.h | 20 +++++++++ sound/usb/usbaudio.h | 45 +++++++++++++++++++ 3 files changed, 184 insertions(+) diff --git a/sound/usb/card.c b/sound/usb/card.c index 3769622..bd59311 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -117,6 +117,117 @@ MODULE_PARM_DESC(skip_validation, "Skip unit descriptor validation (default: no) static DEFINE_MUTEX(register_mutex); static struct snd_usb_audio *usb_chip[SNDRV_CARDS]; static struct usb_driver usb_audio_driver; +static struct snd_usb_audio_vendor_ops *usb_vendor_ops; + +int snd_vendor_set_ops(struct snd_usb_audio_vendor_ops *ops) +{ + if ((!ops->connect) || + (!ops->disconnect) || + (!ops->set_interface) || + (!ops->set_rate) || + (!ops->set_pcm_buf) || + (!ops->set_pcm_intf) || + (!ops->set_pcm_connection) || + (!ops->set_pcm_binterval) || + (!ops->usb_add_ctls)) + return -EINVAL; + + usb_vendor_ops = ops; + return 0; +} +EXPORT_SYMBOL_GPL(snd_vendor_set_ops); + +struct snd_usb_audio_vendor_ops *snd_vendor_get_ops(void) +{ + return usb_vendor_ops; +} + +static int snd_vendor_connect(struct usb_interface *intf) +{ + struct snd_usb_audio_vendor_ops *ops = snd_vendor_get_ops(); + + if (ops) + return ops->connect(intf); + return 0; +} + +static void snd_vendor_disconnect(struct usb_interface *intf) +{ + struct snd_usb_audio_vendor_ops *ops = snd_vendor_get_ops(); + + if (ops) + ops->disconnect(intf); +} + +int snd_vendor_set_interface(struct usb_device *udev, + struct usb_host_interface *intf, + int iface, int alt) +{ + struct snd_usb_audio_vendor_ops *ops = snd_vendor_get_ops(); + + if (ops) + return ops->set_interface(udev, intf, iface, alt); + return 0; +} + +int snd_vendor_set_rate(int iface, int rate, int alt) +{ + struct snd_usb_audio_vendor_ops *ops = snd_vendor_get_ops(); + + if (ops) + return ops->set_rate(iface, rate, alt); + return 0; +} + +int snd_vendor_set_pcm_buf(struct usb_device *udev, int iface) +{ + struct snd_usb_audio_vendor_ops *ops = snd_vendor_get_ops(); + + if (ops) + ops->set_pcm_buf(udev, iface); + return 0; +} + +int snd_vendor_set_pcm_intf(struct usb_interface *intf, int iface, int alt, + int direction) +{ + struct snd_usb_audio_vendor_ops *ops = snd_vendor_get_ops(); + + if (ops) + return ops->set_pcm_intf(intf, iface, alt, direction); + return 0; +} + +int snd_vendor_set_pcm_connection(struct usb_device *udev, + enum snd_vendor_pcm_open_close onoff, + int direction) +{ + struct snd_usb_audio_vendor_ops *ops = snd_vendor_get_ops(); + + if (ops) + return ops->set_pcm_connection(udev, onoff, direction); + return 0; +} + +int snd_vendor_set_pcm_binterval(const struct audioformat *fp, + const struct audioformat *found, + int *cur_attr, int *attr) +{ + struct snd_usb_audio_vendor_ops *ops = snd_vendor_get_ops(); + + if (ops) + return ops->set_pcm_binterval(fp, found, cur_attr, attr); + return 0; +} + +static int snd_vendor_usb_add_ctls(struct snd_usb_audio *chip) +{ + struct snd_usb_audio_vendor_ops *ops = snd_vendor_get_ops(); + + if (ops) + return ops->usb_add_ctls(chip); + return 0; +} /* * disconnect streams @@ -753,6 +864,10 @@ static int usb_audio_probe(struct usb_interface *intf, if (err < 0) return err; + err = snd_vendor_connect(intf); + if (err) + return err; + /* * found a config. now register to ALSA */ @@ -820,6 +935,8 @@ static int usb_audio_probe(struct usb_interface *intf, if (chip->quirk_flags & QUIRK_FLAG_DISABLE_AUTOSUSPEND) usb_disable_autosuspend(interface_to_usbdev(intf)); + snd_vendor_usb_add_ctls(chip); + /* * For devices with more than one control interface, we assume the * first contains the audio controls. We might need a more specific @@ -907,6 +1024,8 @@ static void usb_audio_disconnect(struct usb_interface *intf) card = chip->card; + snd_vendor_disconnect(intf); + mutex_lock(®ister_mutex); if (atomic_inc_return(&chip->shutdown) == 1) { struct snd_usb_stream *as; diff --git a/sound/usb/card.h b/sound/usb/card.h index 87f042d0..81280ac 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -204,4 +204,24 @@ struct snd_usb_stream { struct list_head list; }; +struct snd_usb_substream *find_snd_usb_substream(unsigned int card_num, + unsigned int pcm_idx, unsigned int direction, struct snd_usb_audio + **uchip, void (*disconnect_cb)(struct snd_usb_audio *chip)); + +int snd_vendor_set_ops(struct snd_usb_audio_vendor_ops *vendor_ops); +struct snd_usb_audio_vendor_ops *snd_vendor_get_ops(void); +int snd_vendor_set_interface(struct usb_device *udev, + struct usb_host_interface *alts, + int iface, int alt); +int snd_vendor_set_rate(int iface, int rate, int alt); +int snd_vendor_set_pcm_buf(struct usb_device *udev, int iface); +int snd_vendor_set_pcm_intf(struct usb_interface *intf, int iface, int alt, + int direction); +int snd_vendor_set_pcm_connection(struct usb_device *udev, + enum snd_vendor_pcm_open_close onoff, + int direction); +int snd_vendor_set_pcm_binterval(const struct audioformat *fp, + const struct audioformat *found, + int *cur_attr, int *attr); + #endif /* __USBAUDIO_CARD_H */ diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 1678341..90c68cb 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -184,4 +184,49 @@ extern bool snd_usb_skip_validation; #define QUIRK_FLAG_DSD_RAW (1U << 15) #define QUIRK_FLAG_SET_IFACE_FIRST (1U << 16) +struct audioformat; + +enum snd_vendor_pcm_open_close { + SOUND_PCM_CLOSE = 0, + SOUND_PCM_OPEN, +}; + +/** + * struct snd_usb_audio_vendor_ops - function callbacks for USB audio accelerators + * @connect: called when a new interface is found + * @disconnect: called when an interface is removed + * @set_interface: called when an interface is initialized + * @set_rate: called when the rate is set + * @set_pcm_buf: called when the pcm buffer is set + * @set_pcm_intf: called when the pcm interface is set + * @set_pcm_connection: called when pcm is opened/closed + * @set_pcm_binterval: called when the pcm binterval is set + * @usb_add_ctls: called when USB controls are added + * + * Set of callbacks for some accelerated USB audio streaming hardware. + * + * TODO: make this USB host-controller specific, right now this only works for + * one USB controller in the system at a time, which is only realistic for + * self-contained systems like phones. + */ +struct snd_usb_audio_vendor_ops { + int (*connect)(struct usb_interface *intf); + void (*disconnect)(struct usb_interface *intf); + + int (*set_interface)(struct usb_device *udev, + struct usb_host_interface *alts, + int iface, int alt); + int (*set_rate)(int iface, int rate, int alt); + int (*set_pcm_buf)(struct usb_device *udev, int iface); + int (*set_pcm_intf)(struct usb_interface *intf, int iface, int alt, + int direction); + int (*set_pcm_connection)(struct usb_device *udev, + enum snd_vendor_pcm_open_close onoff, + int direction); + int (*set_pcm_binterval)(const struct audioformat *fp, + const struct audioformat *found, + int *cur_attr, int *attr); + int (*usb_add_ctls)(struct snd_usb_audio *chip); +}; + #endif /* __USBAUDIO_H */ From patchwork Thu Mar 24 08:10:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oh Eomji X-Patchwork-Id: 553925 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3B1BFC433EF for ; Thu, 24 Mar 2022 08:15:02 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 24C83176B; Thu, 24 Mar 2022 09:14:10 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 24C83176B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1648109700; bh=Smfx0akaAFTuH/NGxQHPEDVy4tVnSm0PlRlZV7FZx/8=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=oeR9cc5qLi04fieUn1hv8eLlIiOXffKHGlxlVlJH72guP1kw2hZl4VpsYbaGXjIqZ R6JuVsU0dFx4PQgQt8Q/f9/2IoxrMm59d6W7+oWB0sKYQT6SBirTvtDqtkz4gtVwI2 7W9eZvQjpKtdE+AtvjomhBhIphghcdb4dFyORLK8= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id C0952F80154; Thu, 24 Mar 2022 09:14:09 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 944DFF801EC; Thu, 24 Mar 2022 09:14:08 +0100 (CET) Received: from mailout1.samsung.com (mailout1.samsung.com [203.254.224.24]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 2F4CBF80154 for ; Thu, 24 Mar 2022 09:14:01 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 2F4CBF80154 Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="N0AJy+/P" Received: from epcas2p3.samsung.com (unknown [182.195.41.55]) by mailout1.samsung.com (KnoxPortal) with ESMTP id 20220324081356epoutp01bf70c29dc32ac98782a9fed2de5ea155~fQvuKQ1kl0874408744epoutp01r for ; Thu, 24 Mar 2022 08:13:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.samsung.com 20220324081356epoutp01bf70c29dc32ac98782a9fed2de5ea155~fQvuKQ1kl0874408744epoutp01r DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1648109636; bh=YW/2ceFMHoRfV7fzxxaDnC0GyOKNFo3dhe+3d+i6lhw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=N0AJy+/PLHvo1ayD5Cx1g05PhW6bpL19jEw0SlBrHKsf39CkXBC3Y7hIXKe6XHkrU KZGQiGbyeSogcrZdn73ixtSlg4zuk/J0Q+vexRJxoy/Pirw73BP7QDCrzW9qvji5gC pPfkDeguqrUi7hVYSBMXKl467zmU6muIAUZSYUms= Received: from epsnrtp2.localdomain (unknown [182.195.42.163]) by epcas2p1.samsung.com (KnoxPortal) with ESMTP id 20220324081356epcas2p1966dd6d7123f831434fccf1a9321a3c1~fQvtnieql2232922329epcas2p1G; Thu, 24 Mar 2022 08:13:56 +0000 (GMT) Received: from epsmges2p3.samsung.com (unknown [182.195.36.100]) by epsnrtp2.localdomain (Postfix) with ESMTP id 4KPHzz0Tlcz4x9Q3; Thu, 24 Mar 2022 08:13:51 +0000 (GMT) Received: from epcas2p4.samsung.com ( [182.195.41.56]) by epsmges2p3.samsung.com (Symantec Messaging Gateway) with SMTP id 69.E4.25540.C382C326; Thu, 24 Mar 2022 17:13:49 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas2p4.samsung.com (KnoxPortal) with ESMTPA id 20220324081348epcas2p48d3a24dfdfd8d01e9bf350571b18ffff~fQvmqrMTj0598405984epcas2p4c; Thu, 24 Mar 2022 08:13:48 +0000 (GMT) Received: from epsmgms1p1new.samsung.com (unknown [182.195.42.41]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20220324081348epsmtrp1c3b1a025dd259ecc157f7cf500477fae~fQvmp07mu0419104191epsmtrp1T; Thu, 24 Mar 2022 08:13:48 +0000 (GMT) X-AuditID: b6c32a47-81bff700000063c4-d6-623c283ce36e Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p1new.samsung.com (Symantec Messaging Gateway) with SMTP id F7.7E.29871.C382C326; Thu, 24 Mar 2022 17:13:48 +0900 (KST) Received: from ubuntu.dsn.sec.samsung.com (unknown [12.36.155.120]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20220324081348epsmtip2ea52d3bb30fb2d5b3a180677e31513f5~fQvmdNqXf1325713257epsmtip2A; Thu, 24 Mar 2022 08:13:48 +0000 (GMT) From: Oh Eomji To: Jaroslav Kysela , Takashi Iwai , Greg Kroah-Hartman Subject: [PATCH v1 2/3] sound: usb: Calling vendor's call-back function within usb audio operation. Date: Thu, 24 Mar 2022 17:10:43 +0900 Message-Id: <1648109444-196321-3-git-send-email-eomji.oh@samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1648109444-196321-1-git-send-email-eomji.oh@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrHKsWRmVeSWpSXmKPExsWy7bCmha6thk2SwfmNzBZXLh5isji1fCGT RfPi9WwWU34tZba4vGsOm8WBP4vZLDp39bNabPi+ltGBw2PD5yY2j52z7rJ7bFrVyeaxf+4a do99b5exefRtWcXosX7LVRaPz5vkAjiism0yUhNTUosUUvOS81My89JtlbyD453jTc0MDHUN LS3MlRTyEnNTbZVcfAJ03TJzgE5TUihLzCkFCgUkFhcr6dvZFOWXlqQqZOQXl9gqpRak5BSY F+gVJ+YWl+al6+WlllgZGhgYmQIVJmRnnJt/ib1gr2zFj7MNbA2MEyW6GDk5JARMJI782sfU xcjFISSwg1HibvtsZgjnE6PEo45TzCBVQgLfGCXmbOSD6ejq+QxVtJdRYuGeBywQzg9GiWX/ u8A62ARUJaYv287YxcjBISJQJrFsuiVIDTPIiifvlrKD1AgLpEo8vLYDrJ4FqH7Or242EJtX wFViy7SLjBDb5CRunutkBpnDKeAm8eulO8gcCYFH7BI3FnawQNS4SKw6dIkNwhaWeHV8CzuE LSXxsr8Nyi6WOLjgOVRNjcTbg61QcWOJWc/awe5kFtCUWL9LH8SUEFCWOHILbDqzAJ9Ex+G/ 7BBhXomONiGIRiWJSU2dTBC2hMSKz01QtofEpf97oAE6k1Hi9fwW9gmMcrMQFixgZFzFKJZa UJybnlpsVGAMj6/k/NxNjOCEp+W+g3HG2w96hxiZOBgPMUpwMCuJ8N6/bJ0kxJuSWFmVWpQf X1Sak1p8iNEUGHQTmaVEk/OBKTevJN7QxNLAxMzM0NzI1MBcSZzXK2VDopBAemJJanZqakFq EUwfEwenVAOTjHnXnV2M+005lzf8++nicu125uGXf+3uvWp6rJHYoZl8YNLic9kWG8R3spj4 zT3gxG0Uz9Sd8eSy16eKGcXVd4W+zwtyyN/1w+HD7c/RovZTtZmP1Dte+CSsLvxVrWRLT+tN FtbtpfkvCx4lix26tF/eICnHSsB5N+vkzPItAQrWnTsS7zqJ6m39Ed7CdKZQY1nTqq7QbUJt tpO5LU5Wz351IvaIuYTmmVu1Fxa9t+76Wmey0SJfh2v+BevlGqs4jpxsP2o085tavG2rSmfx 98MT93FNrFjWc+T1utTWFw1F7c97Paefn6vbUyF6kjFeapfY/P2t85v6O/NOPH81zWnd1Nkb lr2ICn1/IfupEktxRqKhFnNRcSIAR75CvQEEAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrFLMWRmVeSWpSXmKPExsWy7bCSvK6Nhk2Swf4GFYsrFw8xWZxavpDJ onnxejaLKb+WMltc3jWHzeLAn8VsFp27+lktNnxfy+jA4bHhcxObx85Zd9k9Nq3qZPPYP3cN u8e+t8vYPPq2rGL0WL/lKovH501yARxRXDYpqTmZZalF+nYJXBnn5l9iL9grW/HjbANbA+NE iS5GTg4JAROJrp7PzF2MXBxCArsZJTat6GCCSEhILOh6zQxhC0vcbznCCmILCXxjlLg+SwPE ZhNQlZi+bDsjiC0iUCFx6+t2sEHMAnsYJZqONoM1CwskS1yb08cOYrMANcz51c0GYvMKuEps mXaREWKBnMTNc51A9RwcnAJuEr9eukPscpXof7mPbQIj3wJGhlWMkqkFxbnpucWGBYZ5qeV6 xYm5xaV56XrJ+bmbGMHBqaW5g3H7qg96hxiZOBgPMUpwMCuJ8N6/bJ0kxJuSWFmVWpQfX1Sa k1p8iFGag0VJnPdC18l4IYH0xJLU7NTUgtQimCwTB6dUA9OB98yP1yyZo6nmKXF7fmej5p1i GYu5TT8/HHSZMHW56ba6V5mOubLOeVWSufeWe2kKP8/zNTXsmpucY6FrE5JZ2V3UJVe32jKx 2P6iV6DbkZZHCSveSdswGH78O6FpIfOG/Q15p5721k5PEXH4du6H5Op9kzvWPzpUEnU/82RF n0OV9TTZK1e9HZafX1ypddP/4ped9T9m/bJMObz9xkKTaj4REY2jMl4FrEWLfoXsyewx+rv2 PuvswzmTVFzCzX6+9KtxnWH2pT395uyU1s2tewV5/9oFG/i+sv5rXqsrJmTyJcbu2v3SjnP/ HFo1khIZDGSkJIqXlbX0XdtkuW1Ciaue1JuXHf18XoXCSizFGYmGWsxFxYkAjBVkb70CAAA= X-CMS-MailID: 20220324081348epcas2p48d3a24dfdfd8d01e9bf350571b18ffff X-Msg-Generator: CA X-Sendblock-Type: AUTO_CONFIDENTIAL CMS-TYPE: 102P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20220324081348epcas2p48d3a24dfdfd8d01e9bf350571b18ffff References: <1648109444-196321-1-git-send-email-eomji.oh@samsung.com> Cc: Oh Eomji , Pavel Skripkin , alsa-devel@alsa-project.org, open list , Leon Romanovsky X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" When a new interface is connected or removed, the call-back functions are called to transmit a command to the hardware. Signed-off-by: Oh Eomji --- sound/usb/pcm.c | 37 +++++++++++++++++++++++++++++++++++++ sound/usb/stream.c | 2 ++ 2 files changed, 39 insertions(+) diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index cec6e91a..4bae4ba 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -144,6 +144,8 @@ find_format(struct list_head *fmt_list_head, snd_pcm_format_t format, found = fp; cur_attr = attr; } + + snd_vendor_set_pcm_binterval(fp, found, &cur_attr, &attr); } return found; } @@ -434,6 +436,7 @@ static int configure_endpoints(struct snd_usb_audio *chip, struct snd_usb_substream *subs) { int err; + struct usb_interface *iface; if (subs->data_endpoint->need_setup) { /* stop any running stream beforehand */ @@ -442,6 +445,13 @@ static int configure_endpoints(struct snd_usb_audio *chip, err = snd_usb_endpoint_configure(chip, subs->data_endpoint); if (err < 0) return err; + + iface = usb_ifnum_to_if(chip->dev, subs->data_endpoint->iface); + err = snd_vendor_set_pcm_intf(iface, subs->data_endpoint->iface, + subs->data_endpoint->altsetting, subs->direction); + if (err < 0) + return err; + snd_usb_set_format_quirk(subs, subs->cur_audiofmt); } @@ -616,8 +626,18 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_usb_substream *subs = runtime->private_data; struct snd_usb_audio *chip = subs->stream->chip; + struct snd_usb_endpoint *ep = subs->data_endpoint; int ret; + ret = snd_vendor_set_pcm_buf(subs->dev, subs->cur_audiofmt->iface); + if (ret) + return ret; + + if (!subs->cur_audiofmt) { + dev_err(&subs->dev->dev, "no format is specified\n"); + return -ENXIO; + } + ret = snd_usb_lock_shutdown(chip); if (ret < 0) return ret; @@ -630,6 +650,13 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) if (ret < 0) goto unlock; + if (snd_vendor_get_ops()) { + ret = snd_vendor_set_rate(ep->cur_audiofmt->iface, + ep->cur_rate, ep->cur_audiofmt->altsetting); + if (!ret) + goto unlock; + } + /* reset the pointer */ subs->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size); subs->inflight_bytes = 0; @@ -1104,6 +1131,11 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream) struct snd_usb_substream *subs = &as->substream[direction]; int ret; + ret = snd_vendor_set_pcm_connection(subs->dev, SOUND_PCM_OPEN, + direction); + if (ret) + return ret; + runtime->hw = snd_usb_hardware; /* need an explicit sync to catch applptr update in low-latency mode */ if (direction == SNDRV_PCM_STREAM_PLAYBACK && @@ -1137,6 +1169,11 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream) struct snd_usb_substream *subs = &as->substream[direction]; int ret; + ret = snd_vendor_set_pcm_connection(subs->dev, SOUND_PCM_CLOSE, + direction); + if (ret) + return ret; + snd_media_stop_pipeline(subs); if (!snd_usb_lock_shutdown(subs->stream->chip)) { diff --git a/sound/usb/stream.c b/sound/usb/stream.c index ceb93d7..26ca696 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -1227,6 +1227,8 @@ static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip, snd_usb_init_pitch(chip, fp); snd_usb_init_sample_rate(chip, fp, fp->rate_max); usb_set_interface(chip->dev, iface_no, altno); + if (protocol > UAC_VERSION_1) + snd_vendor_set_interface(chip->dev, alts, iface_no, 0); } return 0; } From patchwork Thu Mar 24 08:10:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oh Eomji X-Patchwork-Id: 554402 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A5998C433F5 for ; Thu, 24 Mar 2022 08:15:33 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id D5F4317A9; Thu, 24 Mar 2022 09:14:41 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D5F4317A9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1648109731; bh=+rwwqxvIP/4xAYJgK+cWUZcogL+vbIqkJA5mvBt+6Is=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Njlwd0Bp3J7KI9j5BQLGvD3Gz+9UK5ZcYAquem6e2rrQdWDhZNt/teKvLCalvQDzm X/+l3YCVZyV8reVMUmH1WD2jjQRMbrgtqtfN7q+CpYMjsUZqk7so5M21fiAEYYwx7f +ggIi9ydAyXS/2a8208NaDEcsS3Ieb4PTay0ucp8= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 55B5CF80165; Thu, 24 Mar 2022 09:14:12 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 07072F804CA; Thu, 24 Mar 2022 09:14:11 +0100 (CET) Received: from mailout4.samsung.com (mailout4.samsung.com [203.254.224.34]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 7F367F80165 for ; Thu, 24 Mar 2022 09:14:04 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 7F367F80165 Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="PULPdX4A" Received: from epcas2p2.samsung.com (unknown [182.195.41.54]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20220324081359epoutp04c7cd80de4d446e8c9da7c8a1e319ee1d~fQvwzfQ9V1029610296epoutp04U for ; Thu, 24 Mar 2022 08:13:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20220324081359epoutp04c7cd80de4d446e8c9da7c8a1e319ee1d~fQvwzfQ9V1029610296epoutp04U DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1648109639; bh=e2S0AR6UBCgtXFPmuHvVKzU4rCbohW0LJAZA0Loq/YA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PULPdX4AwzieW01ilRbW3rfRyeF8GgzoCQ4qhxB1cjnpBI5DeiYWwc280RrdAyuZk r2M9XVE+YI2VH/74jF65fT0tRmtSJA40Z3OCvzwMvhIn4T+BgGYbHuVczCxm8SHZQb uL02TE37UzQfW3d7g1XtOeGXJBQR1pR178lc440s= Received: from epsnrtp4.localdomain (unknown [182.195.42.165]) by epcas2p2.samsung.com (KnoxPortal) with ESMTP id 20220324081359epcas2p268c4a258c373fb043819c6037a51833c~fQvwhjL4U1822418224epcas2p2g; Thu, 24 Mar 2022 08:13:59 +0000 (GMT) Received: from epsmges2p4.samsung.com (unknown [182.195.36.68]) by epsnrtp4.localdomain (Postfix) with ESMTP id 4KPJ030Fkcz4x9QG; Thu, 24 Mar 2022 08:13:55 +0000 (GMT) Received: from epcas2p4.samsung.com ( [182.195.41.56]) by epsmges2p4.samsung.com (Symantec Messaging Gateway) with SMTP id 9D.37.33036.F382C326; Thu, 24 Mar 2022 17:13:51 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas2p2.samsung.com (KnoxPortal) with ESMTPA id 20220324081350epcas2p227458cb1b530f04a9990bcfc8c3b5703~fQvoosWXC1821118211epcas2p2P; Thu, 24 Mar 2022 08:13:50 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20220324081350epsmtrp183017aa0b80e1fb6315d884a03a7b008~fQvon9KXN0419104191epsmtrp1Z; Thu, 24 Mar 2022 08:13:50 +0000 (GMT) X-AuditID: b6c32a48-d10f0a800000810c-6d-623c283f3f2a Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id FE.26.03370.E382C326; Thu, 24 Mar 2022 17:13:50 +0900 (KST) Received: from ubuntu.dsn.sec.samsung.com (unknown [12.36.155.120]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20220324081350epsmtip2965a363d8426755261811d2042f20be7~fQvoZtCDH1278212782epsmtip2D; Thu, 24 Mar 2022 08:13:50 +0000 (GMT) From: Oh Eomji To: Jaroslav Kysela , Takashi Iwai , Greg Kroah-Hartman Subject: [PATCH v1 3/3] sound: usb: Exynos usb audio offloading driver Date: Thu, 24 Mar 2022 17:10:44 +0900 Message-Id: <1648109444-196321-4-git-send-email-eomji.oh@samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1648109444-196321-1-git-send-email-eomji.oh@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrPKsWRmVeSWpSXmKPExsWy7bCmha69hk2Swexb/BZXLh5isji1fCGT RfPi9WwWU34tZba4vGsOm8WBP4vZLDp39bNabPi+ltGBw2PD5yY2j52z7rJ7bFrVyeaxf+4a do99b5exefRtWcXosX7LVRaPz5vkAjiism0yUhNTUosUUvOS81My89JtlbyD453jTc0MDHUN LS3MlRTyEnNTbZVcfAJ03TJzgE5TUihLzCkFCgUkFhcr6dvZFOWXlqQqZOQXl9gqpRak5BSY F+gVJ+YWl+al6+WlllgZGhgYmQIVJmRnrLmzhrHg9GLGihcXfzA2MH5qZexi5OSQEDCRWLz0 EQuILSSwg1Fi88O0LkYuIPsTo8S8r8uZIJzPjBK7Lx+B67ix8CAjRGIXo0TTzRaoqh+MEof+ nGUGqWITUJWYvmw7UBUHh4hAmcSy6ZYgNcwgK568W8oOUiMs4CZx5scjMJsFqL6vv4EVxOYV cJW4dPAHK8Q2OYmb5zqZQeZwAtX/eukOMkdC4BG7xJbOL1A1LhKvH3axQNjCEq+Ob2GHsKUk Xva3QdnFEgcXPGeDsGsk3h5shYobS8x61g52J7OApsT6XfogpoSAssSRW2ATmQX4JDoO/2WH CPNKdLQJQTQqSUxq6mSCsCUkVnxugrI9JKbP3csOCdCZjBLH/jpMYJSbhTB/ASPjKkax1ILi 3PTUYqMCE3iEJefnbmIEpzwtjx2Ms99+0DvEyMTBeIhRgoNZSYT3/mXrJCHelMTKqtSi/Pii 0pzU4kOMpsCQm8gsJZqcD0y6eSXxhiaWBiZmZobmRqYG5krivF4pGxKFBNITS1KzU1MLUotg +pg4OKUamE78iz+ops0z9aVDfXH22q63s5vCXz09cu1vXpf9FnnFz+X7k+zVw+ven/B0uzDb be/Ep9Nkd0klVtnzPNFTKYiUikqatDZoypTyqYtvLJ/2TTS36EH06hW/3gnFZmx+8CtoJ6/z xk3nJy1Y+LT/6w8udqOv06cph987bFsYZHuzeK/muUuKEqv6d+7UrflhIX3godp65VXz/lmp rBFZxnj06ovNiurfgk9N+nPfd8eGjuUbdO4/ErnR/ux0NGPne4nZM3uN8vb2rbKUnnJlYq9g VvoB/bCI3RN4Ellmv51XXmsqJffg31sW6bP+l/mfMx4/t61GSuvxHq/eueeNi9Zv4brgfp43 7qxhHOMlXtVvSizFGYmGWsxFxYkAkXwGdgIEAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrDLMWRmVeSWpSXmKPExsWy7bCSvK6dhk2SwY52LYsrFw8xWZxavpDJ onnxejaLKb+WMltc3jWHzeLAn8VsFp27+lktNnxfy+jA4bHhcxObx85Zd9k9Nq3qZPPYP3cN u8e+t8vYPPq2rGL0WL/lKovH501yARxRXDYpqTmZZalF+nYJXBlr7qxhLDi9mLHixcUfjA2M n1oZuxg5OSQETCRuLDwIZHNxCAnsYJTYdW0JO0RCQmJB12tmCFtY4n7LEVYQW0jgG6PEtVk2 IDabgKrE9GXbwQaJCFRI3Pq6nRlkELPAHkaJpqPNYM3CAm4SZ348AhvKAtTQ198ANohXwFXi 0sEfrBAL5CRunusEqufg4ASq//XSHWKXq0T/y31sExj5FjAyrGKUTC0ozk3PLTYsMMpLLdcr TswtLs1L10vOz93ECA5QLa0djHtWfdA7xMjEwXiIUYKDWUmE9/5l6yQh3pTEyqrUovz4otKc 1OJDjNIcLErivBe6TsYLCaQnlqRmp6YWpBbBZJk4OKUamARuJKz/V+hYZFb6jCXzIPOyLtPn 3gd/Z2/ZsehFYcSi//GBT8+F2HF+jCs/LyFoq5//ZiGX936T1x80TFq060UfXFzwbFnDKfNb bDrn6kPKJVkvfEz6bnW6VSR2j0rura8LegTv2V8/bi5r7XZt4R4rtsRZ73iMq9ZldRrPzutd KG7Nsn/SDf4Enr3sc3UtfKLn+7+QTkh7+9O+4ca+TH2Hbzt522xXm6Y51zrcWlhfvUP36oTQ Db/P9Nqw9W+ouvKkufMIo0eTn/JZ06+Ls44FXzphu+9uwlLzsCqFS9YLGf4/7Wh9eWumQe9b j74b9udf5kqv98i+dU1RVbHFulHTdLn5f7H7QWmhUZwXlViKMxINtZiLihMBDPe/c78CAAA= X-CMS-MailID: 20220324081350epcas2p227458cb1b530f04a9990bcfc8c3b5703 X-Msg-Generator: CA X-Sendblock-Type: AUTO_CONFIDENTIAL CMS-TYPE: 102P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20220324081350epcas2p227458cb1b530f04a9990bcfc8c3b5703 References: <1648109444-196321-1-git-send-email-eomji.oh@samsung.com> Cc: Oh Eomji , Pavel Skripkin , alsa-devel@alsa-project.org, open list , Leon Romanovsky X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" This is for usb audio offloading. usb audio offloading processes usb audio stream data directly from the audio box even if ap usb enters suspend, there is no problem in stream data transmission. This obtains power saving effect while using usb audio device. AP usb and audio usb f/w communicate via AUDIO IPC. By performing AUDIO IPC in the vendor operations, abox can access and control the xhci to transmit the data directly. The types of commands and data delivered through AUDIO IPC include the following (AP USB <-> AUDIO USB f/w) : 1. usb audio connection/disconnection status 2. xhci memory information 3. full descriptor for usb audio device 4. UAC(usb audio class) control command Signed-off-by: Oh Eomji --- sound/usb/Kconfig | 9 + sound/usb/Makefile | 2 + sound/usb/exynos_usb_audio.c | 560 +++++++++++++++++++++++++++++++++++++++++++ sound/usb/exynos_usb_audio.h | 150 ++++++++++++ 4 files changed, 721 insertions(+) create mode 100644 sound/usb/exynos_usb_audio.c create mode 100644 sound/usb/exynos_usb_audio.h 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 + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#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 "); +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 + * + */ + +#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 */